Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React setState with callback in functional components

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:

enter image description here

So I guess - this functionality is not included into functional components?

like image 632
Slowwie Avatar asked May 15 '26 02:05

Slowwie


1 Answers

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]) 
like image 175
Shubham Khatri Avatar answered May 19 '26 03:05

Shubham Khatri