为了账号安全,请及时绑定邮箱和手机立即绑定

使用反应钩子 useEffect 反应生命周期

使用反应钩子 useEffect 反应生命周期

慕森王 2021-11-25 19:43:28
我目前从改变我的应用程序文件class与生命周期事件,如componentDidMount对functions与useEffect挂钩。对于大多数文件,我没有看到任何问题,但在下面,我遇到了应用程序冻结的性能问题。控制台中的错误或警告为零,但我的机器和 Chrome 增加了此选项卡上使用的内存。我错过了什么?基于旧类的文件代码listener: any;componentDidMount() {  const { firebase } = this.props;  this.listener = firebase.onAuthUserListener(    (authUser: any) => {      localStorage.setItem('authUser', JSON.stringify(authUser));      this.setState({ authUser });    },    () => {      localStorage.removeItem('authUser');      this.setState({ authUser: null });    }  );}componentWillUnmount() {  this.listener();}新的钩子(导致性能问题)const listener = () => {  firebase.onAuthUserListener(    (authUser: any) => {      localStorage.setItem('authUser', JSON.stringify(authUser));      setState(authUser);    },    () => {      localStorage.removeItem('authUser');      setState(null);    }  );};useEffect(() => {  listener();  return () => {    listener();  };});可能还值得注意的是,我正在将 TypeScript 与 React 一起使用。
查看完整描述

3 回答

?
狐的传说

TA贡献1804条经验 获得超3个赞

onAuthUserListener返回一个取消订阅的函数。这应该在组件卸载时使用。


在您的代码中,您没有返回取消订阅功能。


const listener = () => {

  firebase.onAuthUserListener(..)    // problem here no return

}

所以在useEffect你应该正确分配它并在useEffect返回时使用它。


const [user, setUser] = React.useState(null);


useEffect(

  () => {

    //             v------ proper assignment.

    const listener = firebase.onAuthUserListener(

      (authUser: any) => {

        localStorage.setItem('authUser', JSON.stringify(authUser));

        setUser(authUser);

      },

      () => {

        localStorage.removeItem('authUser');

        setUser(null);

      }

    );


    return () => listener();

  }

  , [] // no deps

);


查看完整回答
反对 回复 2021-11-25
?
九州编程

TA贡献1785条经验 获得超4个赞

这里可能是错误:


useEffect(() => {

  listener();

  return () => {

    listener();  <--- here

  };

});

问题是,为了触发listener();呼叫,需要改变什么状态?


我认为这:


const listener = () => {

  firebase.onAuthUserListener(

    (authUser: any) => {

      localStorage.setItem('authUser', JSON.stringify(authUser));

      setState(authUser);

    },

    () => {

      localStorage.removeItem('authUser');

      setState(null);

    }

  );

};

应该转化为一个 React Hook。干杯!


查看完整回答
反对 回复 2021-11-25
?
白板的微信

TA贡献1883条经验 获得超3个赞

useEffect需要一个依赖数组作为第二个参数,否则它会在每次渲染时继续运行。由于您正在更新状态,因此只会不断重复


useEffect(() => {

  listener();

  return () => {

    listener();

  };

}, []);



您可以使用Runaway Effects或 ESLint等工具进行静态分析,以便事先弄清楚这些。


查看完整回答
反对 回复 2021-11-25
  • 3 回答
  • 0 关注
  • 126 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信