useEffect 清理功能,防止卸载组件异步更新

时间:2021-02-21 23:40:42

标签: reactjs asynchronous react-hooks components

我是 React Hooks 的新手。当我从“关于”部分跳到另一部分时会显示此警告。无需等待它完成挂载。

<块引用>

index.js:1 警告:无法对已卸载的对象执行 React 状态更新 成分。这是一个空操作,但它表明您的内存泄漏 应用。修复,取消所有订阅和异步任务 在 useEffect 清理函数中。 在 FadeItems 中(在 AboutSection.jsx:32) 在 div(由 CardBody 创建) 在 CardBody 中(在 AboutSection.jsx:29) 在 div(由 Card 创建) 在卡片中(在 AboutSection.jsx:22) 在 div 中(在 AboutSection.jsx:19) 在 AbouSection(在 About.jsx:9) 在部分(在 About.jsx:7 处) 在关于(由 Context.Consumer 创建)

这是 FadeItems 的代码:

import React, { useState } from "react";
import PropTypes from "prop-types";
import { Fade } from "reactstrap";

const FadeItems = (props) => {

  const [count, setCount] = useState(0);

  // const [mount, setMount] = useState(true);
  // useEffect(() => {
  //   // setTimeout(() => {
  //     // let mounted = true
  //       if (mount) {
  //         mount = false;
  //       }

  //     return function cleanup() {
  //         mounted = false
  //     }
  //     // setCount(0);
  //   // }, 300)
  // }) // prevent the unmounted component to be updated

  const { text } = props;
  return (
    <div style={{ backgroundColor: '#282c34', padding: '30px', borderBottom: "solid 2px #764abc"}}>
      {
        text.map((statement, index) => (
          <Fade
            in={count >= index ? true : false}
            onEnter={() =>
              setTimeout(() => {
                setCount(index + 1);
              }, 2000)
            }
            onExiting={() => setCount(-1)}
            tag="h5"
            className="mt-3"
            key={index + 100}
            style={{ backgroundColor: '#282c34' }}
          >
            {statement}
          </Fade>
        ))
      }
    </div>
  );
};

FadeItems.propTypes ={
  text: PropTypes.string,
}.isRequired;

export default FadeItems;

我有一个计时器设置为在 2 秒后挂载 Fade。由 onEnter 道具调用。挂载后。正如此处的 Reacstrap 文档所建议的那样:

Fade item documentation Reactstrap

代码的注释部分试图用 useEffect 修复。但我还不知道如何正确使用它。 如果要检查存储库:

GitHub Repository

1 个答案:

答案 0 :(得分:1)

需要清除useEffect的清理函数中设置的定时器

 const [mount, setMount] = useState(true);
   useEffect(() => {
      const timerId = setTimeout(() => {
        let mounted = true
         if (mount) {
           mount = false;
         }

      return () => {
         clearTimeout(timerId);
      }
   })