代码之家  ›  专栏  ›  技术社区  ›  SkRoR

如何修复reactjs中无法对未安装组件执行React状态更新的警告

  •  0
  • SkRoR  · 技术社区  · 3 年前

    Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
    

    这是我的密码

     const [userDetail, setUserDetail] = React.useState('');
      const personalDetails = (user_id) => {
        axios
        .get(`http://localhost:3001/users/${user_id}`, { withCredentials: true })
        .then((response) => {
          const personalDetails = response.data;
          setUserDetail(response.data);
        })
        .catch((error) => {
          console.log(" error", error);
        });
      };
      React.useEffect(() => {
       if (user_id) {
        personalDetails(user_id);
      }
    }, [user_id]);
    

    如果我删除useffect调用这个错误消失。这里面有什么问题。请帮忙。

    0 回复  |  直到 3 年前
        1
  •  2
  •   Stephen Jennings    3 年前

    似乎是这样的:

    1. 您的组件已安装。
    2. 无论出于什么原因,组件都会卸载(父组件正在移除它)。
    3. HTTP请求完成,您的回调调用 setUserDetail ,即使组件已卸载。

    另一个问题是你正在定义 personalDetails 在使用效果之外。

    1. 移动身体 个人详细信息 作用于效果内部。
    2. user_id 换了,你就不想打电话了 设置用户详细信息 再也不用了,所以用 aborted 变量来跟踪这个。
    const [userDetail, setUserDetail] = React.useState("");
    
    React.useEffect(() => {
      if (user_id) {
        let aborted = false;
    
        axios
          .get(`http://localhost:3001/users/${user_id}`, { withCredentials: true })
          .then((response) => {
            const personalDetails = response.data;
    
            // Don't change state if the component has unmounted or
            // if this effect is outdated
            if (!aborted) {
              setUserDetail(response.data);
            }
          })
          .catch((error) => {
            console.log(" error", error);
          });
    
        // The function returned here is called if the component unmounts
        // or if the dependency list changes (user_id changes).
        return () => (aborted = true);
      }
    }, [user_id]);