Redux state update causing React component to render unnecessarily


Redux state update causing React component to render unnecessarily



I’m experiencing a few performance issues in my react / redux app.



I’m working with an object in one of my reducers which is quite deep. It contains an object named list which holds a collection of objects.


list


const state = {
list: {
one: {
id: 'one',
name: 'One',
active: false
},
two: {
id: 'two',
name: 'Two',
active: false
}
}
}



Each item in the object is used to render a component. This component will access the properties of the item like so:


const List = (props) => {
const listItems = Object.keys(props.list).map((key) => {
const item = props.list[key];
return (
<Item key={item.id} active={item.active}>
{item.name}
</Item>
);
});

return <ul>{listItems}</ul>;
};



However, every time I run through the following code, my component (which is a PureComponent) renders.


case UPDATE_LIST_ITEM:
return {
...state,
list: {
...state.list,
[payload.itemId]: {
...state.list[payload.itemId],
},
},
};



The Redux docs mention that "every level of nesting must be copied and updated appropriately", yet, I'm not even updating any values, but just copying the object.



I'm not sure what could be done here. Is this a good time to implement a library like Immutable.js?



Update:



Also (I'm not too sure if this helps but), the following redux update does not cause my component to render:


case UPDATE_LIST_ITEM:
return {
...state,
list: {
...state.list,
[payload.itemId]: state.list[payload.itemId],
},
};





Seems like every time your reducer returns a new state, it's going to trigger a re-render on every component that consumes that entire object. Maybe I'm not understanding you. Is your object vastly more complex than that one/two guy above?
– mccambridge
2 days ago





It has a few more properties, but that's about it
– James Moran
2 days ago





I believe the issue is being caused by the object pointer changing and therfore causing a render. I'm wondering whether I should be performing a check to make sure I should return a new/updated copy of the state and whether something like Immutable.js can help with that
– James Moran
2 days ago





What do your mapState functions look like? You're probably handing the PureComponent a section of the state that is being updated, so yes, it will re-render.
– markerikson
2 days ago


mapState


PureComponent





I'm not too sure what you mean. I have a section where I map over Object.keys(props.list) to render the list items (shown in my question)
– James Moran
2 days ago


Object.keys(props.list)




1 Answer
1



Your pure component is using props.list from the state. In your first reducer, by the time your code reaches that point you are updating the application state and if your component is getting list from the application state, the expected behaviour to re-render your component if the props value has changed.


props.list


list



If you do not want your component to re-render on every state change, you can control that with have to upgrade your component to class and control when and when not it should render. shouldComponentUpdate(nextProps, nextState)


shouldComponentUpdate(nextProps, nextState)



React docs





My list item is a class though (as it's a PureComponent). My understanding was that PureComponents implements its own shallow prop and state comparison, so there would not be a reason to use shouldComponentUpdate
– James Moran
2 days ago



shouldComponentUpdate





The react docs also mention: "Consider using the built-in PureComponent instead of writing shouldComponentUpdate() by hand. PureComponent performs a shallow comparison of props and state, and reduces the chance that you’ll skip a necessary update."
– James Moran
2 days ago





Your main concern was that component is re-rendering unnecessarily right? What I see happening basically is this: case UPDATE_LIST_ITEM: is invoked and state changes. mapStateToProps updating ` <List />` which is causing your pure component to re render. Maybe you are dispatching unnecessarily which is causing the unwanted rerenders?
– Matthew Barbara
2 days ago



case UPDATE_LIST_ITEM:






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Comments

Popular posts from this blog

paramiko-expect timeout is happening after executing the command

Export result set on Dbeaver to CSV

Opening a url is failing in Swift