3

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?

halfer
  • 19,824
  • 17
  • 99
  • 186
Slowwie
  • 1,146
  • 2
  • 20
  • 36

1 Answers1

3

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]) 
Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400
  • 1
    Yes thank u. I found the solution with the if (successfullyCreatedCard !== {}) by myself. But the thing with the useRef sounds interesting. I don't completly undestand it yet but I will learn it. Thank u. – Slowwie May 16 '20 at 17:46