I have built a simple counter app:
class Counter extends React.Component {
constructor(props) {
super(props);
this.handleAddOne = this.handleAddOne.bind(this);
this.handleMinusOne = this.handleMinusOne.bind(this);
this.handleReset = this.handleReset.bind(this);
this.state = {
count: 0
};
}
componentDidMount() {
const stringCount = localStorage.getItem('count');
const count = parseInt(stringCount);
if (isNaN(count) === false) {
this.setState(() => ({ count }));
}
}
componentDidUpdate(prevProps, prevState) {
if (prevState.count !== this.state.count) {
localStorage.setItem('count', this.state.count);
console.log('componentDidUpdate');
}
}
handleAddOne() {
this.setState((prevState) => {
return {
count: prevState.count + 1
}
});
}
handleMinusOne() {
console.log('handleMinusOne');
this.setState((prevState) => {
return {
count: prevState.count - 1
}
});
}
handleReset() {
this.setState(() => {
return {
count: 0
}
});
}
render() {
return (
<div>
<h1>Count: {this.state.count}</h1>
<button onClick={this.handleAddOne}>+</button>
<button onClick={this.handleMinusOne}>-1</button>
<button onClick={this.handleReset}>reset</button>
</div>
);
}
}
ReactDOM.render(<Counter />, document.getElementById('app'));
The question I have is with componentDidUpdate()
. In it, I am checking to see if the prevState.count
is not the same as the this.state.count
. If it is not the same, then I set localStorage
to the new count. If it is same, I do nothing.
In the current componentDidUpdate(), I need prevProps
as an argument for this function to work correctly. For example, if I just have this:
componentDidUpdate(prevState) {
if (prevState.count !== this.state.count) {
localStorage.setItem('count', this.state.count);
console.log('componentDidUpdate');
}
}
Then the component sets localStorage
every time the reset button is pressed repeatedly, even though the count remains at 0.
What is going on? Why do I need prevProps
for componentDidUpdate()
to work correctly, if I am never using props
in that function?
Syntax: componentDidUpdate(prevProps, prevState, snapshot) Parameters: Following are the parameter used in this function: prevProps: Previous props passed to the component. prevState: Previous state of the component. snapshot: Value returned by getSnapshotBeforeUpdate() method.
prevState() is the same as the setState but the only difference between them is that if we want to change the state of a component based on the previous state of that component, we use this. setState() , which provides us the prevState . Let's check an example of a counter app.
componentDidMount() will be rendered immediately after a component is mounted. This method will render only once and all the initialization that requires DOM nodes should go here. Setting state in this method will trigger a re-rendering. componentDidUpdate() is invoked immediately every time the updating occurs.
The componentDidUpdate() hook is used to trigger an action once we find an update in the component, but make sure this hook method does not get called at the time of the initial render of the component.
The first parameter in componentDidUpdate
is prevProps
. The second parameter is prevState
. The documentation clearly states that:
componentDidUpdate(prevProps, prevState, snapshot)
This
componentDidUpdate(prevState) {...}
is not a correct signature for the hook. Even though the first parameter was called prevState
, it contains previous props.
It's possible to alternate function parameters based on its arity but this isn't implemented in React and considered a bad practice in general because this leads to more complex signatures.
To not cause linter warnings, unused parameters can be underscored by convention:
componentDidUpdate(_prevProps, prevState) {...}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With