const [count, setCount] = useState(0);
const handleClick = () =>
setCount(prevCount => {
return prevCount + 1;
});
const [count, setCount] = useState(0);
const handleClick = () => setCount(count + 1);
Coming from class-based component background, it becoming a habit where we use functional setState
. I'm wondering if do we still need to rely on prevState in functional hooks? Or the current state is always "trustable" and most "updated"?
setState with the useState & useEffect hooks in React. This is a brief explanation of two of the most widely used hooks in React — useState & useEffect. There is also an example of how to replace a class component with a functional component and still declare and update state through the use of hooks.
Always use the setState() method to change the state object, since it will ensure that the component knows it's been updated and calls the render() method.
Hooks are functions that let you “hook into” React state and lifecycle features from function components. Hooks don't work inside classes — they let you use React without classes. (We don't recommend rewriting your existing components overnight but you can start using Hooks in the new ones if you'd like.)
Safe to use setState ? Yes! This method is called whenever there is an update in the props or state. This method has arguments called nextProps and nextState can be compared with current props and currentState .
Yes, the behavior is similar.
React is batching the updates calls. When Writing:
const handleClick = () => setCount(count + 1)
handleClick()
handleClick()
handleClick()
the count
in state will be 1
When Writing:
const handleClick = () =>
setCount(prevCount => {
return prevCount + 1;
});
handleClick()
handleClick()
handleClick()
the count
in state will be 3
State updater function is necessary in both class and functional components. this.setState
shouldn't be used together with this.state
, the same applies to useState
state and state setter. There are more cases for useState
when not using state updater will result in wrong behaviour.
In class components, the only problem with the use of this.state
is race condition due to asynchronous state updates:
componentDidMount() {
this.setState({ count: this.state.count + 1 });
this.setState({ count: this.state.count + 1 }); // overwrites with stale count
console.log(this.state.count); // not updated
}
When there are no race conditions, this.state
can be accessed anywhere inside a component because this
reference stays the same:
componentDidMount() {
this.setState({ count: this.state.count + 1 });
setTimeout(() => {
this.setState({ count: this.state.count + 1 });
}, 100)
setTimeout(() => {
console.log(this.state.count);
}, 200)
}
In functional components, the problem with the use of useState
state is function scope. There's no object like this that could be accessed by reference, a state is accessed by value which won't be updated until a component is re-rendered:
const [count, setCount] = useState(0);
useEffect(() => {
// runs once on mount
// count is always 0 in this function scope
setCount({ count: count + 1 });
setTimeout(() => {
setCount({ count: count + 1 }); // overwrites with stale count
}, 100)
setTimeout(() => {
console.log(count); // not updated
}, 200)
}, []);
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