我们正在创建一个大型前端应用程序。
我们正在使用React-Redux
我们正在创建一些可重用的组件。
**这个问题是关于在同一页面/路线上有多个相同的可重复使用的redux反应组件的实例**
问题详情:
我们有一个Sectionheader组件。它与redux状态绑定。
它侦听header属性reducer SectionheaderReducer。
由于我们在页面上有2个此Sectionheader实例,因此它们都会显示相同的值,因为它们绑定到同一个store-property。
如何使基于redux的可重用反应组件可配置。因此每个实例可以为减速器具有不同的header属性值SectionheaderReducer
答案 0 :(得分:34)
您需要实现一些命名空间实例的方法。这可以像传入一个键来区分组件和减速器一样基本。
您可以使用ownProps
函数中的mapStateToProps
来指导映射到命名空间
const mapStateToProps = (state, ownProps) {
let myState = state[ownProps.namespace]
return {
myState.value
}
}
可以使用相同的方法将命名空间传递给mapDispatchToProps
const mapDispatchToProps = (dispatch, ownProps) {
return {
myAction: (myParam) => dispatch(myAction(ownProps.namespace, myParam))
}
}
请记住在动作类型中使用命名空间,以便减速器不会踩到脚趾
const myAction => (namespace, myParam) {
return { type: `${namespace}/${MY_TYPE_CONSTANT}`, myParam }
}
并确保reducer也是命名空间
const myReducer = (namespace) => (state = initialState, action) => {
switch(action.type) {
case `${namespace}/${MY_TYPE_CONSTANT}`:
return { ...state, action.myParam }
default:
return state
{
}
现在在组合reducers
时添加2个名称空间缩减器combineReducers({
myInstance1 : myReducer('myInstance1')
myInstance2 : myReducer('myInstance2')
}
最后将命名空间传递给每个实例
render() {
return (
<div>
<MyComponent namespace='myInstance1' />
<MyComponent namespace='myInstance2' />
</div>
)
}
免责声明:我是以下图书馆的主要撰稿人。
redux-subspace可以提供更高级的命名空间实现,而无需为希望拥有多个实例的每个组件重新实现此模式。
创建reducer与上面的类似
const reducer = combineReducers({
myInstance1: namespaced('myInstance1')(myReducer)
myInstance2: namespaced('myInstance2')(myReducer)
})
然后SubspaceProvider
可用于切换每个组件的状态
render() {
return (
<div>
<SubspaceProvider mapState={state => state.myInstance1} namespace='myInstance1'>
<MyComponent />
</SubspaceProvider>
<SubspaceProvider mapState={state => state.myInstance2} namespace='myInstance2'>
<MyComponent />
</SubspaceProvider>
</div>
)
}
确保您还要更改mapStateToProps
函数,以便从提供程序中映射的子树开始遍历
const mapStateToProps = (state) {
return {
state.value
}
}
如果您希望减少嵌套,还有一个Higher-Order Component。
答案 1 :(得分:2)
我已经以不同的方式实现了它,而没有用命名空间实际更改动作名称。
相反,我添加了infra函数,它们将拦截动作创建者并为每个动作添加meta-data
。 (关注FSA
)
这样您就不需要更改减速器或mapStateToProps
功能。
它也与redux-thunk
兼容。
应该易于使用...... reducer-action-interceptor
答案 2 :(得分:0)
我将问题解释为:
<SectionHeader />
)一种可能的解决方案是,将“节”的概念添加到商店中。您将创建用于管理数据内容结构的化简器。例如。一次的存储状态可能看起来像这样:
{
sections: {
0: {
header: 'My section title',
content: 'Whatever your content is'
},
1: {
header: 'My other section title',
content: 'Loads of lovely writing or hrefs to images or whatever'
}
}
}
```
然后,您将拥有一个“容器组件”或“布局组件”或“智能组件”(它们有很多名称),“知道”您要在特定页面上使用第2节和第4节。如何知道这取决于您。也许您对索引进行了硬编码(因为它始终是相同的),也许您有一个过滤规则,也许您在商店中还有另一个字段定义了选择...等等。
然后,容器组件会将选定的标题传递到“哑巴”中,也许像这样:
<SectionHeader>{sections[2].header}</SectionHeader>
或
<SectionHeader title={sections[2].header} />
答案 3 :(得分:0)
将我们的组件转换为哑(无状态)组件,以便这些组件可以轻松重用而不会出现任何复杂情况。