Reputation: 6629
I'm using PureComponent
for better performance in my React application and it has props
but I don't want it to run render method when this props
changed. I know we can not use shouldComponentUpdate
in React.PureComponent
but my question is:
Is there any way to avoid updating React.PureComponent
?
I want this component don't update/render at all.
Edit :
I'm getting this warning when using shouldComponentUpdate
in pureComponent:
Warning: GameObjectFall has a method called shouldComponentUpdate(). shouldComponentUpdate should not be used when extending React.PureComponent. Please extend React.Component if shouldComponentUpdate is used.
Upvotes: 5
Views: 15946
Reputation: 281686
PureComponent
changes the life-cycle method shouldComponentUpdate and adds some logic to automatically check whether a re-render is required for the component. This allows a PureComponent to call method render only if it detects changes in state or props, hence, one can change the state in many components without having to write extra checks.
However you can additionally use the proven method shouldComponentUpdate
to manually determine the necessity of a new re-render.
It doesn't override the PureComponent logic but adds any other things that you added in the custom implementation of shouldComponentUpdate
As of v16.9.0, React throws the following warning
Warning: shouldComponentUpdate should not be used when extending React.PureComponent. Please extend React.Component if shouldComponentUpdate is used.
See a snippet which illustrates this
class App extends React.Component {
state = {
count1: 0,
count2: 0,
count3: 0
}
increment = (key) => {
this.setState(prevState => ({[key]: prevState[key] + 1}))
}
render() {
console.log('render parent');
return (
<div>
{this.state.count1}
<Child count={this.state.count1} countNew={this.state.count3}/>
<button onClick={() => this.increment('count1')}>IncrementOne</button>
<button onClick={() => this.increment('count2')}>IncrementTwo</button>
</div>
)
}
}
class Child extends React.Component {
shouldComponentUpdate(nextProps, nextState) {
console.log('scu');
if (nextProps.count !== this.props.count) {
return false;
}
}
render() {
console.log('render child');
return (
<div>Child: {this.props.count}</div>
)
}
}
ReactDOM.render(<App/>, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"/>
Upvotes: 6
Reputation: 10631
When using PureComponent
, there is an implementation to the method shouldComponentUpdate
which does only a shallow comparison.
You should use it when your props are Boolean, string or any other primitive type.
You can implement your implementation to shouldComponentUpdate
which will override the default shallow comparison.
When I say shallow comparison I mean that if you were compare between objects/arrays, you would get wrong comparison. For example:
const first = { key: 'value' };
const second = { key: 'value' };
if (first === second) {
// You won't get here
}
Upvotes: 0
Reputation: 1727
According to PureComponent Documentation it only does a shallow comparison in shouldComponentUpdate()
. Hence, if all your props are wrapped in an object and if you mutate the properties within that object, component will not re-render since shallow comparison will always result in true.
As an example assume propContainer = {name: "John", age: "20"}
and this.props.container = propContainer
, then mutation within propContainer object (changing name, age values) will not re-render the component.
Upvotes: 2