title: Best way to deal with 'Can't call setState on an unmounted component' react warning
body: <p>You guys have probably seen this error, if not it usually looks something like this:</p>
  <pre><code>Can't perform a React state update on an unmounted component.
  This is a no-op, but it indicates a memory leak in your application.
  </code></pre>
  <p>Firstly this isn't a question about what the error means. It seems to me that there are some cases when this warning is (as far as I can tell) a bit unjustified.</p>
  <p>Consider this component</p>
  <pre><code>() =&gt; {
    const [foo, setFoo] = useState(false)
  
    return (
      &lt;&gt;
        &lt;p&gt;Is foo: {foo}&lt;/p&gt;
        &lt;button onClick={() =&gt; {
          setFoo(true)
          window.setTimeout(() =&gt; setFoo(false), 1000)
        }}&gt;Click me&lt;/button&gt;
      &lt;/&gt;
    )
  }
  </code></pre>
  <p>Ok, so in this contrived example we wanna show <code>Is foo: true</code> for 1 second after the button is clicked. If the component unmounts during that second it's going to call setFoo and we'll get that warning. As far as I can tell, this isn't a memory leak. It might be holding onto setFoo a bit longer than necessary but this won't build up over time, the timer will release setFoo albeit slightly later than it could. Am I missing something? My boss is telling me to get rid of the warning but to cancel the timeout adds a bunch of complexity to something which shouldn't be complex, and imo not going to offer any meaningful performance benefit.</p>
  <p>This lead me to this idea:</p>
  <pre><code>export default () =&gt; {
    const [state, setState] = useState(true)
    useEffect(() =&gt; () =&gt; setState(false), [])
    return state
  }
  </code></pre>
  <pre><code>const useSafeState = &lt;T extends unknown&gt;(defaultState: T): [T, (newState: T) =&gt; void] =&gt; {
    const [state, setState] = useState&lt;T&gt;(defaultState)
    const isMounted = useIsMounted()
  
    return [
      state,
      (newState: T) =&gt; {
        if (isMounted) {
          setState(newState)
        }
      },
    ]
  }
  </code></pre>
  <p>by changing the first example to use <code>useSafeState</code> it automatically checks, effectively suppressing the warning. What do you guys think of this? Use safe state functionally does nothing, because as the react warning states it's a no op. I feel like the warning is there for when people forget to cancel their setIntervals from their useEffect, but for these other scenarios we're forced to do something silly like this just to get rid of the warning.</p>
  <p>Thoughts?</p>