Reputation: 1246
I have a very simple example I wrote in a class component:
setErrorMessage(msg) {
this.setState({error_message: msg}, () => {
setTimeout(() => {
this.setState({error_message: ''})
}, 5000);
});
}
So here I call the setState()
method and give it a callback as a second argument.
I wonder if I can do this inside a functional component with the useState hook.
As I know you can not pass a callback to the setState function of this hook. And when I use the useEffect
hook - it ends up in an infinite loop:
So I guess - this functionality is not included into functional components?
Upvotes: 3
Views: 2203
Reputation: 281646
The callback functionality isn't available in react-hooks, but you can write a simple get around using useEffect
and useRef
.
const [errorMessage, setErrorMessage] = useState('')
const isChanged = useRef(false);
useEffect(() => {
if(errorMessage) { // Add an existential condition so that useEffect doesn't run for empty message on first rendering
setTimeout(() => {
setErrorMessage('');
}, 5000);
}
}, [isChanged.current]); // Now the mutation will not run unless a re-render happens but setErrorMessage does create a re-render
const addErrorMessage = (msg) => {
setErrorMessage(msg);
isChanged.current = !isChanged.current; // intentionally trigger a change
}
The above example is considering the fact that you might want to set errorMessage from somewhere else too where you wouldn't want to reset it. If however you want to reset the message everytime you setErrorMessage, you can simply write a normal useEffect like
useEffect(() => {
if(errorMessage !== ""){ // This check is very important, without it there will be an infinite loop
setTimeout(() => {
setErrorMessage('');
}, 5000);
}
}, [errorMessage])
Upvotes: 4