Reputation: 3577
I am rendering a tabList
, onclick
of any tab it will be highlighted. I am achieving this by checking a selected
attribute.
Everytime a tab is clicked I am changing selected
to true/false
in my reducer
.
myTabsReducer
should not mutate but return a new array.
Am I doing it right way? As per documentation We should not mutate state (should not alter state). In my case I'm altering my reducer
. Is it Ok to do it or is there any other way to achieve it?
export const myTabsReducer = (id) => {
return [
{
id: 1,
name:"My Tab 1",
selected: id==1?true:false
},
{
id: 2,
name:"My Tab 2",
selected: id==2?true:false
},
{
id: 3,
name:"My Tab 3",
selected: id==3?true:false
}
]
}
const myActiveTabReducer = (state = {}, action) => {
switch (action.type) {
case SELECT_PLAN_TAB:
return action.payload
default:
return 1;
}
}
const allReducers = (state = {}, action) => {
return {
allTabs: myTabsReducer(myActiveTabReducer(state, action)),
}
}
Upvotes: 1
Views: 111
Reputation: 579
It would be much better to have your state in this way:
const initialState = {
tabs: [
{ id: 1, name: 'Tab 1' },
{ id: 2, name: 'Tab 2' }
],
selectedTab: 1
}
so that your reducer changes only the selectedTab property on "SELECT_PLAN_TAB":
const activeTabReducer = (state = initialState, action) => {
switch (action.type) {
case SELECT_PLAN_TAB:
return {
...state,
selectedTab: action.payload
};
default:
return state;
}
}
Then, if you need the tabs array with the selected property for each tab, I would use a selector: see http://redux.js.org/docs/recipes/ComputingDerivedData.html
Upvotes: 2
Reputation: 905
You are not mutating the array. Every time reducer is called you generate a new array.
const foo1 = allReducers({}, {type:' SELECT_PLAN_TAB', payload: 1})
const foo2 = allReducers({}, {type:' SELECT_PLAN_TAB', payload: 1})
console.log(foo1.allTabs === foo2.allTabs) // false
You should be careful, because this function will always return new instance even if input stays the same. This means that shallow equality check will fail and depending on how you consume this store, your component will always re-render.
Upvotes: 0