简体   繁体   English

清理 function 第一次使用 AbortController 失败

[英]Cleanup function fails the first time using AbortController

Im using AbortController to cancel the fetch promise on unmount React lifecycle.我使用AbortController在卸载 React 生命周期中取消fetch promise。 For some reason, the cleanup is not working the FIRST TIME the element unmounts .出于某种原因,清理在元素 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.快速单击Show/hide pokemon按钮 TWICE 以强制中止Pokemon反应元素。
  3. Check the error in console: Can't perform a React state update on an unmounted component检查控制台中的错误: 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.重复步骤 2。快速单击Show/hide pokemon按钮 TWICE 以强制中止Pokemon反应元素。
  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 .注意:abort()被调用时, fetch() promise 会拒绝一个名为AbortErrorDOMException

When component unmounts and abort invoked, the fetch rejects with error.当组件卸载并调用abort时, fetch会因错误而拒绝。 The error is caught and this code is attempting to set state with the error.错误被捕获,并且此代码正在尝试使用错误设置 state。 Omitting this error state update removes the react error.省略此错误 state 更新会删除反应错误。

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.我也愿意打赌每次都会发生错误,但反应只是输出第一个错误并让 output 静音以处理后续错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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