简体   繁体   中英

Cleanup function fails the first time using AbortController

Im using AbortController to cancel the fetch promise on unmount React lifecycle. For some reason, the cleanup is not working the FIRST TIME the element unmounts .

  useEffect(() => {
    const controller = new AbortController();
    const signal = controller.signal;
    fetch(`https://pokeapi.co/api/v2/pokemon/${name}`, { signal })
      .then(sleeper(1)) // Create some latency
      .then(res => res.json())
      .then(response => {
        setData(response);
      })
      .catch(error => {
        setData(error);
      });
    return () => {
      controller.abort();
    };
  }, [name]);

Demo

Follow the next steps:

  1. Access de demo link.
  2. Click Show/hide pokemon button TWICE quicly to force the abort of the child Pokemon react element.
  3. Check the error in console: Can't perform a React state update on an unmounted component
  4. Repeat step 2. Click Show/hide pokemon button TWICE quicly to force the abort of the child Pokemon react element.
  5. No errors found this time and subsequent retries. Why?

AbortController

Note: When abort() is called, the fetch() promise rejects with a DOMException named AbortError .

When component unmounts and abort invoked, the fetch rejects with error. The error is caught and this code is attempting to set state with the error. Omitting this error state update removes the react error.

useEffect(() => {
  const controller = new AbortController();
  const signal = controller.signal;
  fetch(`https://pokeapi.co/api/v2/pokemon/${name}`, { signal })
    .then(sleeper(1)) // Create some latency
    .then(res => res.json())
    .then(response => {
      setData(response);
    })
    .catch(error => {
      setData(error); // <-- this is being called after component unmounts!
    });
  return () => {
    controller.abort();
  };
}, [name]);

I'd also be willing to bet that the error occurs every time but react is just outputting the first and silencing output for subsequent errors.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM