Redux:组织容器、组件、动作和化简器
Redux: organising containers, components, actions and reducers
问题:
在大型中组织容器、组件、动作和减速器的最可维护和推荐的最佳实践是什么 React/Redux application?
我的意见:
目前的趋势似乎是围绕相关的容器组件组织redux抵押品(动作,化简器,传奇......)。
/src
/components
/...
/contianers
/BookList
actions.js
constants.js
reducer.js
selectors.js
sagas.js
index.js
/BookSingle
actions.js
constants.js
reducer.js
selectors.js
sagas.js
index.js
app.js
routes.js
这很好用!尽管此设计似乎存在一些问题。
问题:
当我们需要访问 actions
,从另一个容器selectors
或sagas
,这似乎是一种反模式。假设我们有一个全局/App
容器,其中包含一个化简器/状态,用于存储我们在整个应用中使用的信息,例如类别和可枚举项。从上面的示例开始,使用状态树:
{
app: {
taxonomies: {
genres: [genre, genre, genre],
year: [year, year, year],
subject: [subject,subject,subject],
}
}
books: {
entities: {
books: [book, book, book, book],
chapters: [chapter, chapter, chapter],
authors: [author,author,author],
}
},
book: {
entities: {
book: book,
chapters: [chapter, chapter, chapter],
author: author,
}
},
}
如果我们想在/BookList
容器中使用/App
容器中的selector
,我们需要在/BookList/selectors.js
中重新创建它(肯定是错误的?或者从/App/selectors
导入它(它将始终是完全相同的选择器..?这两种掌声对我来说似乎都不是最佳的。
这个用例的主要例子是身份验证(啊...我们确实喜欢讨厌你),因为它是一个非常常见的"副作用"模型。我们经常需要在整个应用程序中访问/Auth
传奇、操作和选择器。我们可能有容器/PasswordRecover
、/PasswordReset
、/Login
、/Signup
....实际上,在我们的应用程序中,我们的/Auth
contianer 根本没有实际组件!
/src
/contianers
/Auth
actions.js
constants.js
reducer.js
selectors.js
sagas.js
简单地包含上面提到的各种通常不相关的身份验证容器的所有 Redux 抵押品。
我个人使用ducks-modular-redux提案。
这不是"官方"推荐的方式,但它对我来说效果很好。每个"鸭子"包含一个actionTypes.js
、actionCreators.js
、reducers.js
、sagas.js
和selectors.js
文件。为了避免循环依赖或鸭子圈,这些文件没有对其他鸭子的依赖,每个"鸭子"只包含它必须管理的逻辑。
然后,在根目录上,我有一个components
和一个containers
文件夹以及一些根文件:
components/
文件夹包含我的应用程序的所有纯组件
containers/
文件夹包含从上述纯组件创建的容器。当容器需要涉及许多"鸭子"的特定selector
时,我将其写入编写<Container/>
组件的同一文件中,因为它是相对于该特定容器的。如果selector
在多个容器中共享,我会在单独的文件中(或在提供这些 props 的 HoC 中创建它)。
rootReducers.js
: 通过组合所有化简器来简单地暴露根化简器
rootSelectors.js
公开每个状态切片的根选择器,例如,在您的情况下,您可以有类似以下内容:
/* let's consider this state shape
state = {
books: {
items: { // id ordered book items
...
}
},
taxonomies: {
items: { // id ordered taxonomy items
...
}
}
}
*/
export const getBooksRoot = (state) => state.books
export const getTaxonomiesRoot = (state) => state.taxonomies
它让我们在每个鸭子selectors.js
文件中"隐藏"状态形状。由于每个selector
都会接收鸭子内部的整个状态,因此您只需在selector.js
文件中导入相应的rootSelector
即可。
rootSagas.js
组成鸭子内部的所有传奇故事,并管理涉及许多"鸭子"的复杂流程。
所以在您的情况下,结构可能是:
components/
containers/
ducks/
Books/
actionTypes.js
actionCreators.js
reducers.js
selectors.js
sagas.js
Taxonomies/
actionTypes.js
actionCreators.js
reducers.js
selectors.js
sagas.js
rootSelectors.js
rootReducers.js
rootSagas.js
当我的"鸭子"足够小时,我经常跳过文件夹创建,直接写一个ducks/Books.js
或ducks/Taxonomies.js
文件,将所有这5个文件(actionTypes.js
,actionCreators.js
,reducers.js
,selectors.js
,sagas.js
)合并在一起。
- React+Redux性能优化与组件ShouldUpdate
- 类叶组件中的connect()是react+redux中反模式的标志吗
- reactjs-redux,是否可以有一个由2个组件使用的状态
- 组件道具更改后更新redux存储
- Redux-组件不同的方法(智能/哑点/容器/演示)
- 有没有更好的方法来处理窗口属性&React/Redux中的子组件
- 在 React/Redux 中管理同级组件之间的滚动状态
- 如何在使用高阶组件进行身份验证时延迟检查redux存储
- 在Redux中使用组件状态是反模式的吗
- Redux和React-通过@connect保持组件道具与状态同步
- 如何从React Redux中的子组件进行调度
- 如果使用Redux和React Redux,则无需React组件中的状态
- 如何使用React和Redux在嵌套容器中测试组件
- Redux - 繁重的工作应该在哪里发生 - 化简器,动作,容器或表示组件
- 当 redux 状态更新时,在组件上调用 forceUpdate()
- 连接在 Redux-react 中无法使用 Stateless 组件
- redux-form 是 卸载组件后破坏我的状态,什么给了
- React Redux 子组件获取父组件设置的全局属性,而无需通过 props 传递它
- Redux - 智能组件 - 在挂载组件之前如何处理异步操作
- 在导出过程中将组件连接到 redux 和多个库