【发布时间】:2018-05-27 22:30:54
【问题描述】:
我一直遵循学习 React 开发的广泛建议,首先掌握组件 props,将 UI 状态封装在组件级别 this.state 并通过组件树有选择地向下传递。这是一次启发性的经历。我开始欣赏无状态视图设计模式的强大功能,并且觉得我已经能够使用这些技术实现稳健且组织良好的结果。
继续前进,我现在尝试使用redux 整合更复杂的状态管理。但是当我涉足复杂性并将redux 集成到我的应用程序中时,我发现自己面临以下关于我的代码如何演变的观察。其中一些发展似乎是明智的,但另一些让我怀疑我做的事情是否“正确”。
1) Action Creators 作为业务和 UI 逻辑的纽带
我发现以前在 React 生命周期函数 componentDidUpdate 等和 onTouch/onPress 处理程序中实现的大部分逻辑现在都在 action creators 中实现了。这似乎是一个积极的发展,因为它将“所有东西都放在同一个地方”并允许进行单元测试。
问题:将业务逻辑集中在一个由相当复杂的动作创建者组成的网络中是否是最佳实践?
2) 挖空reducers
作为上述#1 的推论,我发现我的reducers 和它们对应的action 对象已经演变成一个事实上的设置器列表,它们只不过是使用传递的值更新状态存储,以这种方式:
case types.SAVE_ORDER:
return Object.assign({}, state, {
order: action.order,
});
其中很大一部分原因是reducers 应该是纯函数,因此我可以用它们做的事情受到限制(例如,没有异步处理)。此外,reducer 只允许在它们各自的存储状态子部分上运行。鉴于我的应用程序的大部分复杂性已经必然存在于 action creators 中,我发现很难证明仅仅为了让它们“看起来有用”而将复杂性迁移到 reducers 是合理的。
问题:有样板文件reducers 仅作为 redux 存储状态的美化设置器,这是否正常且可接受的做法?
3) redux-thunk 无处不在
我已经单独询问了为什么redux-thunk 甚至是必要的(而不是在异步回调/实用程序函数中调用标准操作创建者)。我被 Dan Abramov 指出了这个answer,它提供了一个非常令人满意的解释(相对于可扩展性、服务器端渲染和无数其他原因)。
接受redux-thunk 的必要性后,我发现我的大多数动作创建者需要执行异步动作,需要访问getState,或dispatch 多次更改状态.结果,我一直在广泛地返回“thunks”。
问题:Redux 应用程序广泛依赖thunk'ed 动作创建者,并且很少直接触发标准对象动作是否正常?
4) Redux 作为全局 this.state
归根结底,我的应用程序的redux 商店似乎已经演变为有效地类似于全球this.state。您可以将其视为将整个应用程序状态保留在最外层容器组件中的 this.state 中,但没有将所述 state 向下传递到 props 的嵌套层所带来的不可避免的混乱,并且任何更改都会备份组件树通过 handler 函数的老鼠巢。
问题:redux 是用于全局状态存储的正确工具吗?是否有替代品的行为更类似于 react 的内置 this.state,允许通过无状态的 react 组件传播全局应用程序状态,并通过集中的 ' 从整个应用程序更新switchboard',没有采用 redux 带来的看似无穷无尽的样板、常量和 switch 语句网络?
5) 一种单一的动作类型? 此后续问题的灵感来自已发布的 cmets 之一。
问题:一个人是否可以合法地(严肃地说,不仅仅是公然证明一个观点)将 redux 与一种操作类型一起使用?
示例 - 动作创建者:
export function someActionCreator(various_params){
return (dispatch, getState => {
// ... business logic here ....
asyncIfThisIfThat().then(val => {
dispatch({
// type: 'UPDATE_STATE', // Don't even bother setting a type
order: val
})
})
)
}
通用减速机案例:
export default function app(state = initialState, action = {}) {
return Object.assign({}, state, action)
// Just unconditionally merge into state!
}
在我看来,这将提供一个全局范围的状态对象,该对象自动映射到connected 组件,并且受益于不可变状态的所有优点,并且可以与 React props 互操作。在这个方案中,dispatch实际上变成了一个全局的setState。
注意 - 请不要误会这个问题 - 这当然不是对 redux 的批评。作为一名学习者,我显然无法评判一项由数千人的专业知识和数百万人支持的技术。我毫不怀疑它在正确的上下文中的价值。
我只是在自己的代码中感觉到了可疑模式的味道,想知道我做错了什么,或者我是否使用了正确的工具来完成任务。
【问题讨论】:
-
你不需要 redux 样板。您可以使用单个减速器进行单个操作,它仍然可以工作。您添加多少样板完全取决于您,以及您想要的详细程度。 @markerikson 有一个 redux 博客和大量资源,可以回答您的所有其他问题 github.com/markerikson/react-redux-links
标签: reactjs react-native redux react-redux frontend