Ответ 1
Вам нужно реализовать какой-то способ пространства имен экземпляров. Это может быть так же просто, как передача ключа для дифференциации компонентов и редукторов.
Вы можете использовать ownProps
в вашей функции mapStateToProps
для направления отображения в пространство имен.
const mapStateToProps = (state, ownProps) {
let myState = state[ownProps.namepspace]
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 }
}
И убедитесь, что редуктор тоже находится в пространстве имен
const myReducer = (namespace) => (state = initialState, action) => {
switch(action.type) {
case '${namespace}/${MY_TYPE_CONSTANT}':
return { ...state, action.myParam }
default:
return state
{
}
Теперь добавьте 2 редуктора пространства имен при комбинировании редукторов
combineReducers({
myInstance1 : myReducer('myInstance1')
myInstance2 : myReducer('myInstance2')
}
Наконец, передайте пространство имен каждому экземпляру
render() {
return (
<div>
<MyComponent namespace='myInstance1' />
<MyComponent namespace='myInstance2' />
</div>
)
}
Отказ от ответственности: я являюсь основным автором следующей библиотеки.
redux-subspace может предоставить более продвинутую реализацию пространства имен без необходимости переопределения этого шаблона для каждого компонента, для которого вы хотите иметь несколько экземпляров.
Создание редукторов аналогично приведенному выше
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
}
}
Существует также компонент высшего порядка, если вы предпочитаете уменьшать вложенность.