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

我目前从改变我的应用程序文件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 一起使用。


慕森王
浏览 127回答 3
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);

九州编程

这里可能是错误:useEffect(() => {&nbsp; listener();&nbsp; return () => {&nbsp; &nbsp; listener();&nbsp; <--- here&nbsp; };});问题是,为了触发listener();呼叫,需要改变什么状态?我认为这:const listener = () => {&nbsp; firebase.onAuthUserListener(&nbsp; &nbsp; (authUser: any) => {&nbsp; &nbsp; &nbsp; localStorage.setItem('authUser', JSON.stringify(authUser));&nbsp; &nbsp; &nbsp; setState(authUser);&nbsp; &nbsp; },&nbsp; &nbsp; () => {&nbsp; &nbsp; &nbsp; localStorage.removeItem('authUser');&nbsp; &nbsp; &nbsp; setState(null);&nbsp; &nbsp; }&nbsp; );};应该转化为一个 React Hook。干杯!

白板的微信

useEffect需要一个依赖数组作为第二个参数,否则它会在每次渲染时继续运行。由于您正在更新状态,因此只会不断重复useEffect(() => {&nbsp; listener();&nbsp; return () => {&nbsp; &nbsp; listener();&nbsp; };}, []);您可以使用Runaway Effects或 ESLint等工具进行静态分析,以便事先弄清楚这些。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript