Slowwie
Slowwie

Reputation: 1246

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?

Upvotes: 3

Views: 2203

Answers (1)

Shubham Khatri
Shubham Khatri

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

Related Questions