问题:
在大型组织中组织容器,组件,操作和减速器的最可维护和建议的最佳实践是什么 React/Redux申请?
我的观点:
目前的趋势似乎是在相关容器组件周围组织redux抵押品(行动,减速器,传奇......)。 e.g。
/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
时,它似乎是一种反模式。假设我们有一个带有reducer / state的全局/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,
}
},
}
如果我们要在selector
容器中的/App
容器中使用/BookList
,我们需要在/BookList/selectors.js
中重新创建它(肯定是错的?)或导入它来自/App/selectors
(它总是与EXACT相同的选择器吗??不。)。这些appraoches对我来说都不是最理想的。
此用例的主要示例是身份验证(啊...我们确实喜欢讨厌你,因为它是非常常见的“副作用”模型。我们经常需要在整个应用中访问/Auth
传奇,动作和选择器。我们可能有容器/PasswordRecover
,/PasswordReset
,/Login
,/Signup
....实际上,在我们的应用中,/Auth
contianer根本没有实际组件!
/src
/contianers
/Auth
actions.js
constants.js
reducer.js
selectors.js
sagas.js
简单地包含上面提到的各种且通常不相关的auth容器的所有Redux附属品。
答案 0 :(得分:5)
我个人使用ducks-modular-redux提案。
这不是“官方”推荐方式,但对我来说效果很好。每个“duck”包含actionTypes.js
,actionCreators.js
,reducers.js
,sagas.js
和selectors.js
个文件。这些文件中没有依赖于其他ducks来避免循环依赖或duck circle,每个“duck”只包含它必须管理的逻辑。
然后,在根目录中我有一个components
和一个containers
文件夹以及一些根文件:
components/
文件夹包含我应用的所有纯组件
containers/
文件夹包含从上面的纯组件创建的容器。当容器需要一个涉及许多“鸭子”的特定selector
时,我将其写在我编写<Container/>
组件的同一文件中,因为它与此特定容器相关。如果selector
共享accros多个容器,我在一个单独的文件中创建它(或在提供这些道具的HoC中)。
rootReducers.js
:通过组合所有reducer来简单地公开root reducer
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
它让我们“隐藏”每个duck selectors.js
文件中的状态形状。由于每个selector
都会在您的鸭子中收到整个州,因此您只需在rootSelector
个文件中导入相应的selector.js
。
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
当我的“鸭子”足够小时,我经常跳过文件夹创建并直接写一个包含所有这5个文件的ducks/Books.js
或ducks/Taxonomies.js
文件(actionTypes.js
,{{1 }},actionCreators.js
,reducers.js
,selectors.js
)合并在一起。