2017-05-08 161 views
3

我来自RefluxRedux。在回流你的业务逻辑是只存在于店内但终极版它似乎“终极版” different..for比如我有“异步行动”和我一起“终极版 - 咚”付诸实施。将业务逻辑放在哪里?动作或商店

在一个场景中,我想检查我的操作中的某些内容,如果需要我向服务器发送请求并获取一些数据。我这种情况下,我必须检查我的行动逻辑,实际上我的业务逻辑是存在的行动和存储在一起,它不好..你的解决方案是什么?

,比如我有复选框,我检查一些条件,如果结果为真我将请求发送到服务器,这里是我的动作代码,当你看到我的商业逻辑是对我的行动,我的减速机:

export function onCheckboxClick({itemId}) { 
    return (dispatch, getState) => { 
     let state = getState().get('myReducer'); 

     let myConditionResult = state.get('foods').get(0).get('test');//for exmaple check some condition in my store 

     dispatch({type: 'CHECKBOX_CLICK', itemId});// for change the checkbox checked 

     if (myConditionResult) { 
     myApi.deleteOrderItem({itemId}).then(()=> { 
      dispatch({type: 'DELETE_ORDER_ITEM_FULFILLED', itemId}); 
     }).catch((err)=> { 
      console.log(err); 
      dispatch({type: 'DELETE_ORDER_ITEM_REJECTED', itemId}); 
     }); 
     } 
    }; 
} 

在此先感谢

+0

驾驶室,你是更具体的条件是什么之前,必须满足你发送一个动作,使一个HTTP请求? – meteorBuzz

+0

@meteorBuzz感谢您的回复我更新了我的问题 –

回答

4

如前所述,根据您的使用情况,有多种方式可以执行此操作。我能做的是列出你猜测你的用例似乎更合适的东西。

1.组件内的逻辑。

持有的条件能通过映射状态使用connect道具react-redux

带入分量也导入行动到这个组件文件和地图的动作道具以及状态。

下面的示例演示了如何将状态和操作引入组件文件。你如何使用它取决于你。我已经把它放在一个简单的上下文中。所以你可以在你希望执行逻辑的地方调用myFunction()

MyComponenet。JS

import React, { Component} from 'react' 
import { connect } from 'react-redux' 
import { onCheckboxClick } from 'path/to/action' 

class MyComponenet extends Component { 

    myFunction() { 
     const { theConditiion, onCheckboxClick } = this.props 

     if (theConditiion) { 
      onCheckboxClick({itemId: 'someItemid'}) 
     } 
    } 

    render() { 
     //... 
    } 
} 


const mapStateToProps = (state) => ({ 
    theConditiion: state.wherever.the.data.lives.in.store 
}) 

export default connect(
    mapStateToProps, 
    { onCheckboxClick } 
    )(MyComponenet) 

因此,您可以将您onCheckboxClick功能上面的例子中删除您目前拥有的条件检查。

2.将逻辑放入中间件中。

下面的示例演示了如何分派动作,但首先'捕捉'特定类型的动作,如果条件为真,您可以进行api调用并分派进一步的动作(如果为false) ,只需将该操作传递给下一个中间件。

myMiddleware.js

const onCheckboxClick = store => next => action => { 
    if (action.type == 'CHECKBOX_CLICK') { 

    let theConditiion = store.getState().wherever.the.data.lives.in.store 

    if (theConditiion) { 
     // 1. make the api call here, or, 
     // 2. dispatch an action specific to handling api calls. 
     // E.g. Create another middleware to catch action type `API_CALL` 
     // This middleware can then handle all api calls, and dispatch actions for api requests, responses and errors. 

     const newAction = {...action, type: 'API_CALL' } 
     store.dispatch(newAction) 

     // When you use store.dispatch(), the action will be passed back to the top of the middleware chain. 
    } 

    return next(action) // this will pass the action to the next middleware in the chain. 

} 

export default onCheckboxClick 

这是一个广泛的概述,以帮助你在想什么效果最好。请记住,随着您的应用程序的发展,您会注意到重复的逻辑可以用于自己的功能。

3

引述Redux FAQ entry on "how to split business logic between action creators and reducers"

有没有单一明确的答案的逻辑件应在减速或动作去什么创造者。

如果你把所有的逻辑放在动作创建器中,你最终会得到基本上声明状态更新的胖动作对象。减速器变得纯粹,笨拙,添加 - 删除它,更新这些功能。他们将很容易撰写。但是你的业务逻辑不会太多。如果你在reducer中加入更多的逻辑,你最终会得到很好的精简动作对象,大部分的数据逻辑集中在一个地方,但是你的reducer很难编写,因为你可能需要来自其他分支的信息。你最终会得到大型减速器或减速器,这些减速器或减速器会从该州的较高位置获得额外的参数。

它是有效的调度是得到由减速器忽视的作用,而且它也适用于先检查状态,并决定派遣一个动作。最终,它确实符合您的需求。

0

以下是一些反对REDX建议的自以为是的答案。

TL; DR 无论

较长的答案:在所谓的异步操作中间件调用。在redux社区它被称为“thunk”或“saga”。

首先,一些定义:

  • 动作:一个普通的对象{ type: 'ACTION_TYPE', payload: { data } }
  • 动作创建者:返回动作的功能。
  • 异步操作:从中间件调用的函数。
  • 异步行动的创建者:返回异步操作
  • 中间件的功能:它可以处理所有的动作,调度等措施,先后获得存储状态的功能。

那么,我们从哪里调用业务逻辑呢?

如果你仔细观察,你会发现,我们并不需要异步操作异步行动的创建者。我们可以有一个简单的动作,它直接在中间件中处理。

中间件,我们可以为每个行动专用处理。这处理程序行为像异步操作但我们不这样称呼它。我们称之为交互者

所以一个新的定义:

交互件:什么本质上是终极版异步操作,但终极版特有的不是抽象的。交互器获取数据,调用业务逻辑并分派结果“动作”。

middleware = (...) => { 
    // if(action.type == 'HIGH_LEVEL') 
    interactors[action.name]({ dispatch, params: action.payload }) 
} 

const interactors = { 
    async highLevelAction({ dispatch, params }) { 
    dispatch({ loading: true }); 
    const data = await api.getData(params.someId); 
    const processed = myPureLogic(data); 
    dispatch({ loading: false, data: processed }); 
    } 
} 

如何分派吧:

dispatch({ type: 'HIGH_LEVEL', name: 'highLevelAction', { someId: 1 } }) 
相关问题