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

在useffect()中生成清除函数的警告时有发生

  •  0
  • yudhiesh  · 技术社区  · 4 年前

    我正在使用AWS Amplify,当用户注销时,我会收到一个警告:

    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.
    

    它提到它发生在 Profile.tsx 文件,这是useffect()钩子。

    但问题是错误发生了 有时 .

    我一直在测试它,它来了又去,我不知道为什么会这样。

     function Profile() {
    
      const [user, setUser] = useState<IIntialState | null>(null);
    
      useEffect(() => {
        checkUser();
        Hub.listen("auth", data => {
          const { payload } = data;
          if (payload.event === "signOut") {
            setUser(null);
          }
        });
      }, []);
    
      async function checkUser() {
        try {
          const data = await Auth.currentUserPoolUser();
          const userInfo = { username: data.username, ...data.attributes };
          console.log(userInfo);
          setUser(userInfo);
        } catch (err) {
          console.log("error: ", err);
        }
      }
      function signOut() {
        Auth.signOut().catch(err => console.log("error signing out: ", err));
      }
      if (user) {
        return (
          <Container>
            <h1>Profile</h1>
            <h2>Username: {user.username}</h2>
            <h3>Email: {user.email}</h3>
            <h4>Phone: {user.phone_number}</h4>
            <Button onClick={signOut}>Sign Out</Button>
          </Container>
        );
      }
      return <Form setUser={setUser} />;
    }
    
    0 回复  |  直到 4 年前
        1
  •  1
  •   Odinn    4 年前

    之所以发生这种情况,是因为您卸载了组件,但其中仍有订阅。

    提供卸载功能:

      useEffect(() => {
        Hub.listen("auth", func);
        return () => {
        // unsubscribe here
         Hub.remove("auth", signOut)
        };
     });
    

    你的中心类有remove方法

    remove(channel: string | RegExp, listener: HubCallback): void
    

    删除中的订阅 使用效果 返回函数

    Hub.remove()

        2
  •  1
  •   Indranil    4 年前

    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.

    这个信息很直截了当。我们正在尝试更改组件的状态,即使它已卸载且不可用。

    出现这种情况的原因有很多,但最常见的是我们没有取消订阅websocket组件,或者在异步操作完成之前卸载了websocket组件。要解决此问题,您可以执行以下操作之一:

     useEffect(() => {
        checkUser();
        //check howto remove this listner in aws documentation  
        const listner= Hub.listen("auth", data => {
          const { payload } = data;
          if (payload.event === "signOut") {
            setUser(null);
          }
        });
    
        //this return function is called on component unmount 
        return ()=>{/* romve the listner here */}
      }, []);
    
    

    或者用这个简单的方法。

     useEffect(() => {
        let mounted =true
        Hub.listen("auth", data => {
          const { payload } = data;
          if (payload.event === "signOut" && mounted ) {
            setUser(null);
          }
        });
    
    
         //this return function is called on component unmount 
        return ()=>{mounted =false }
      }, []);
    
    

    阅读更多关于 this here .