title: How to cleanup async tasks created outside useEffect
body: <p>I created a custom hook <code>useFetch</code> that returns a <code>fetch</code> function that I can use in other components. It uses a promise to fetch some data inside. My goal is to clean up the pending promise, if the component, that uses this custom hook gets unmounted.</p>
  
  <p>How would I do it? I tried something using <code>useRef</code>, but without success yet. Still getting the <code>Can't perform a React state update on an unmounted component.</code> warning.</p>
  
  <pre><code>const useFetch = (url) =&gt; {
    const [isFetching, setIsFetching] = useState(false)
    const handler = useRef(null)
  
    useEffect(() =&gt; () =&gt; {
      if (handler.current !== null) {
        handler.current.cancel()
      }
    }, [])
  
    return (options) =&gt; {
      handler.current = window.fetch(url, options)
      setIsFetching(true)
  
      return handler.current.then(() =&gt; {
        handler.current = null
        setIsFetching(false)
      })
    }
  }
  
  export default () =&gt; {
    const fetchData = useFetch('www.tld')
  
    useEffect(() =&gt; {
      fetchData({}).then(() =&gt; console.log('done'))
    }, [])
  
    return null
  }
  </code></pre>
  
  <p>Notice that the promise in this example is cancelable via <code>.cancel()</code> (so thats not a problem here).</p>