Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
129
rated 0 times [  132] [ 3]  / answers: 1 / hits: 23173  / 7 Years ago, mon, march 20, 2017, 12:00:00

We are creating a large front-end application.


We are using React-Redux for it


We are creating some reusable components.


This question is regarding having multiple instance of same reusable redux react components on the same page/route


Problem details:


We have a Sectionheader component. Which is bound to redux state.


It listens to the header property reducer SectionheaderReducer.


As we have 2 instances of this Sectionheader on the page both tend to show same values as they are bound to the same store state-property.


How to make the redux based reusable react component configurable? So that each instance can have different value of header property for reducer SectionheaderReducer


More From » reactjs

 Answers
6

You need to implement some way of namespacing the instances. This can be as basic as passing in a key to differentiate the components and reducers.



You can use the ownProps in your mapStateToProps function to guide the mapping to a namespace



const mapStateToProps = (state, ownProps) {
let myState = state[ownProps.namespace]
return {
myState.value
}
}


The same method can be used to pass on a namespace to the mapDispatchToProps



const mapDispatchToProps = (dispatch, ownProps) {
return {
myAction: (myParam) => dispatch(myAction(ownProps.namespace, myParam))
}
}


Just remember to use the namespace in the action type so the reducers don't tread on toes



const myAction => (namespace, myParam) {
return { type: `${namespace}/${MY_TYPE_CONSTANT}`, myParam }
}


And make sure the reducer is namespaced too



const myReducer = (namespace) => (state = initialState, action) => {
switch(action.type) {
case `${namespace}/${MY_TYPE_CONSTANT}`:
return { ...state, action.myParam }
default:
return state
{
}


Now add the 2 namespaced reducers when combining reducers



combineReducers({
myInstance1 : myReducer('myInstance1')
myInstance2 : myReducer('myInstance2')
}


Finally pass the namespace to each instance



render() {
return (
<div>
<MyComponent namespace='myInstance1' />
<MyComponent namespace='myInstance2' />
</div>
)
}


Disclaimer: I am the main contributor on the following library.



redux-subspace can provide a more advanced namespacing implementation without you having to reimplement this pattern for every component you want to have multiple instances for.



Creating the reducers is similar to above



const reducer = combineReducers({ 
myInstance1: namespaced('myInstance1')(myReducer)
myInstance2: namespaced('myInstance2')(myReducer)
})


Then SubspaceProvider can be used to switch out the state for each component



render() {
return (
<div>
<SubspaceProvider mapState={state => state.myInstance1} namespace='myInstance1'>
<MyComponent />
</SubspaceProvider>
<SubspaceProvider mapState={state => state.myInstance2} namespace='myInstance2'>
<MyComponent />
</SubspaceProvider>
</div>
)
}


Just ensure you also change your mapStateToProps function to so start traversing from the subtree mapped in the provider



const mapStateToProps = (state) {
return {
state.value
}
}


There is also a Higher-Order Component if you prefer to reduce nesting.


[#58475] Friday, March 17, 2017, 7 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
havenbilliec

Total Points: 324
Total Questions: 106
Total Answers: 94

Location: Pitcairn Islands
Member since Fri, Oct 15, 2021
3 Years ago
;