【问题标题】:How to fix this React useEffect error " Warning: Can't perform a React state update on an unmounted component."如何修复此 React useEffect 错误“警告:无法对未安装的组件执行 React 状态更新。”
【发布时间】:2021-09-04 07:32:39
【问题描述】:

我有 2 个仪表板 1 供用户和其他管理员使用,并且导航上有主页按钮,它重定向到 userdashboard 管理员用户的角色定义为管理员

如果他点击主页按钮,我在这里使用 useEffect 挂钩将管理员重定向到 admindashboard,

export default function Dashboard() {
  const user = useSelector((state) => state.user);
  const role = user.user_info.roles;
  const history = useHistory();

  useEffect(() => {
    if (role === "admin") {
      history.push("/admin-dashboard");
    }
  }, []);

  return (
    <React.Fragment>
      <Banner />
      <Row1 />
      <Row2 />
      <Row3 />
      <Row4 />
      <Row5 />
      <Row6 />
    </React.Fragment>
  );
}

Banner n 每一行都是映射视频

export default function Row1() {
  const history = useHistory();

  const [videos, setVideos] = useState([]);

  useEffect(() => {
    const getData = async () => {
      const data = await getAllVideosTopRated();
      setVideos(data);
    };

    getData();
  }, []);

  const handleClick = (id) => {
    history.push(`/videoplayer/${id}`);
  };

  const responsive = {
    desktop: {
      breakpoint: { max: 3000, min: 1024 },
      items: 5,
      slidesToSlide: 3,
    },
    laptop: {
      breakpoint: { max: 1024, min: 768 },
      items: 3,
      slidesToSlide: 2, // optional, default to 1.
    },
    tablet: {
      breakpoint: { max: 768, min: 464 },
      items: 2,
    },
    mobile: {
      breakpoint: { max: 464, min: 330 },
      items: 1,
    },
    mobileSmall: {
      breakpoint: { max: 320, min: 0 },
      items: 1,
      slidesToSlide: 1, // optional, default to 1.
    },
  };

  return (
    <React.Fragment>
      <Container maxWidth="xl" className="row">
        <h2>Top Rated</h2>
        {videos !== null && videos.length ? (
          <Carousel responsive={responsive} swipeable={true}>
            {videos.map((item) => (
              <div className="row_thumbnails" key={item.id}>
                <img
                  onClick={() => handleClick(item.id)}
                  className="row_thumbnail"
                  src={item.thumbnail}
                  alt={item.title}
                />
              </div>
            ))}
          </Carousel>
        ) : (
          <Loader />
        )}
      </Container>
    </React.Fragment>
  );
}

这是 getAllvideos api 调用

let data = null;

export const getAllVideos = async () => {
  await axios
    .post(`${apis.all}`)
    .then((res) => {
      data = res.data;
    })
    .catch((err) => {
      console.log(err);
    });
  return data;
};

它按预期重定向,但浏览器控制台中的每一行都出现上述错误

【问题讨论】:

  • (1) 在文本中是正确的,它只是一个警告,以及 (2) 你在哪里排队任何状态更新?这是一个完整的代码示例吗?
  • 你的Banner 里面有什么,你的Dashboard 周围有什么?
  • 嘿@DrewReese,我们见过很多次了,老板!只想说“嗨”
  • 只是浏览器控制台中的错误日志其他事情很好,它在我的管理仪表板上进行
  • Hii @RyanLe 学习是一项艰巨的任务xD

标签: javascript reactjs use-effect


【解决方案1】:

您有一个setState,它可能在history.push 之后运行

快速修复:

删除useEffect:

useEffect(() => {
  if (role === "admin") {
    history.push("/admin-dashboard");
  }
}, []);

收件人:

if (role === "admin") {
    history.push("/admin-dashboard");
}

这样做,您的Row(n) 将没有机会呈现,因此 API 不会开始获取。


说明:

在这个区块中:

useEffect(() => {
  const getData = async () => {
    const data = await getAllVideosTopRated();
    setVideos(data);
  };

  getData();
}, []);

你是 awaitgetAllVideosTopRated 完成然后 setVideos(data),但 Dashboard 中的 history.push 首先被触发,然后你的 async 函数仍在继续,setState 而你的组件已经已卸载。

这就是为什么您会看到具有相同含义的错误

【讨论】:

  • 我试过你的解决方案删除了​​ useEffect 它像以前一样在管理仪表板上运行,但控制台错误现在更改为“警告:在现有状态转换期间无法更新(例如在 render 内)。渲染方法应该成为 props 和 state 的纯函数。在 Dashboard"
  • 这是另一个问题,伙计。可能与您的 admin-dashboard 组件有关。您可以就此提出另一个问题。
  • 无论如何,当您在组件尚未完成渲染时尝试更改状态时会发生该错误。
  • 我只是使用 window.location.replace 而不是 history.push 它在控制台中没有错误。如果角色是管理员,window.location.replace 是否不会让仪表板进一步呈现?
  • @chaitu605 使用window.location.replace 将重新加载您的应用程序,因此所有待处理的状态更新都会被清除(警告消失的原因)。在重新初始化/获取之前,您在内存中的任何状态也是如此。
猜你喜欢
  • 2021-12-03
  • 1970-01-01
  • 1970-01-01
  • 2023-03-06
  • 1970-01-01
  • 2021-03-27
  • 2019-09-11
  • 2021-08-07
  • 2020-06-14
相关资源
最近更新 更多