I came across some weird behavior that I would feel safer to understand
Below is the code of my reducer. I can not get why, but with this code the component tied to the redux state does not re-render . I can tell with the developper tools that the state is properly updated.
const initialState = {
allItems: [],
favItems: [],
}
export default (state = initialState, action) => {
let allItems
case CREATE_ITEM:
allItems = state.allItems
allItems.unshift(action.item)
return {
...state,
allItems: allItems,
}
}
Comparing with other actions in my reducer, I finally guess that there was something about the time cost of the operation, some other operations a bit more complicated seemed to work better...
So I added a timer
case CREATE_ITEM:
allItems = state.allItems
allItems.unshift(action.item)
setTimeout(() => {
return {
...state,
allItems: allItems,
}
}, 0)
And boom, it worked !
I really don't like this highly hacky solution.
Does anyone has any idea about what is happening and how I could solve this in a better way.
Notes :
useSelector
hookconst items = useSelector((state) => state.items.allItems)
"allItems.unshift(action.item)" adds data directly to the reducer state, because allItems is referenced to redux state variable. So before returning the state you are updating the reducer. After returning the state there won't be any change in the redux data so component is not getting re-rendered.
For better understanding refer to this answer https://stackoverflow.com/a/48819216/7822241
Here is the solution, with the help of Mohan Krisgna Sai answer.
I was indeed mutating the state without knowing it, because when you assign a variable to a reference type (ie: an object), the variable only holds a reference to the memory location where the object is actually stored, not the actual object itself. Further details here : https://stackoverflow.com/a/50840423/13337619
So, this, is mutating the state
allItems = state.allItems
allItems.unshift(action.item)
The solution is straightforward :
case CREATE_ITEM:
return {
...state,
allItems: [action.item, ...state.allItems],
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.