Reputation: 1126
I have a react component that is a list, let's call it List, it has a state named items that is an array of object of the form :
{ id: String, name: String }
its render function is something like
render () {
return (
<ul>
{ items.map((item) => {
return (
<Item key={item.id} item={item} />
);
})}
</ul>
);
}
with Item being a react component too, of course.
So now, my question: let's say that at one point, I know that the data changed (it can only be a name change, of course), how can I trigger Item to refresh based on its key from the parent?
I found two solutions so far :
so what's a 'reactier' way of doing this?
Upvotes: 3
Views: 6851
Reputation: 490
By implementing shouldComponentUpdate(nextProps, newState) in your React components you can calculate whether or not the component needs to update. So if you send a whole new object in, this should trigger already in its default implementation (they don't do a deep-compare), but if the property input.name
is changed then it will not detect this. So you could implement this yourself like this:
shouldComponentUpdate(nextProps, newState) {
return this.props.name === nextProps.name; // use === to compare types too!
}
Now I'm a bit rusty on the JavaScript (I prefer TypeScript), so I am not sure if this is the correct way to compare strings.
Upvotes: 1
Reputation: 116
Using the shouldComponentUpdate() method, you can specify whether or not a component should update based on the current props and the new props which are provided as:
shouldComponentUpdate(nextProps){
return this.props.item.name !== nextProps.item.name;
}
Here's a JsFiddle with a demo: https://jsfiddle.net/Vorcan/Lakj6qwb/
Usually, you have to create a new object instance using something like Object.assign().
Other than the docs, another good resource to check out shouldComponentUpdate is https://developmentarc.gitbooks.io/react-indepth/content/life_cycle/update/using_should_component_update.html
Upvotes: 0
Reputation: 281696
If the items array changed then the render of the Parent
is called, since the keys Item
components are same, the component is not re-created but its componentWillReceiveProps
function is called and the Item component is re-rendered.
What you can do as an optimization is to create a Item component as a Pure component which you can do by extending React.PureComponent
. React.PureComponent’s
shouldComponentUpdate()
only shallowly compares the objects so if the Props haven't changed a rerender on child is not called.
According to the DOCS:
If your React component’s render() function renders the same result given the same props and state, you can use React.PureComponent for a performance boost in some cases.
React.PureComponent’s
shouldComponentUpdate()
only shallowly compares the objects. If these contain complex data structures, it may produce false-negatives for deeper differences. Only extendPureComponent
when you expect to have simple props and state, or useforceUpdate()
when you know deep data structures have changed. Or, consider using immutable objects to facilitate fast comparisons of nested data.Furthermore,
React.PureComponent’s
shouldComponentUpdate()
skips prop updates for the whole component subtree. Make sure all the children components are also “pure”.
Upvotes: 3