如何将componentDidMount()和componentWillUnmount转换为useEffect()?

时间:2020-09-15 13:28:46

标签: javascript reactjs

我正在尝试创建一个弹出窗口,通知用户如果导航离开,请按保存进度。我需要将以下代码转换为钩子:

class Prompt extends React.Component {
  componentDidMount() {
    window.addEventListener('beforeunload', this.beforeunload.bind(this));
  }

  componentWillUnmount() {
    window.removeEventListener('beforeunload', this.beforeunload.bind(this));
  }

  beforeunload(e) {
    if (this.props.dataUnsaved) {
      e.preventDefault();
      e.returnValue = true;
    }
  }

  render() {...}
}

我知道我应该使用useEffect(),但是由于我一般不熟悉钩子,因此不确定如何使用。特别是我不确定第二个参数是什么,因为钩子不喜欢this.bind。任何帮助将不胜感激。

4 个答案:

答案 0 :(得分:2)

根据React Docs:

如果您熟悉React类的生命周期方法,可以考虑 useEffect Hook作为componentDidMount,componentDidUpdate和 componentWillUnmount组合在一起。

因此componentDidMount将是:

useEffect(() => { // yourCode },[])

并且由于componentWillUnmout用于清理See React Docs,因此您可以像这样使用它作为回报:

useEffect(() => {
  window.addEventListener('beforeunload', () => {});

  return () => {
    window.removeEventListener('beforeunload', () => {})
  }
}, [])

答案 1 :(得分:1)

您可以像这样使用useEffect:

useEffect(() => {
// like componentDidMount
 return function cleanup() {
    // like componentWillUnmount
  };
}, [exampleProp]);

useEffect仅在第二个自变量中的一个道具已更改时才会触发。如果不传递第二个参数,则useEffect类似于componentDidUpdate。 有关更多信息,请访问:https://reactjs.org/docs/hooks-effect.html

答案 2 :(得分:1)

我认为是这样的,我没有测试,但是在这段代码中,useEffect将在安装时以及prop“ dataUnsaved”发生任何更改时运行,而return语句将在ummount组件中运行,请阅读更多内容。 React docs中有关清除功能的内容。

function Prompt({dataUnsaved}) {
  useEffect(() => {
    const beforeunload = (e) => {
      e.preventDefault();
      e.returnValue = true;
    }

    window.addEventListener("beforeunload", beforeunload);

    return () => {
      window.removeEventListener("beforeunload", beforeunload);
    }
  }, [dataUnsaved]);

  return <div />
}

答案 3 :(得分:1)

您可以通过以下方式对以上代码使用钩子:

function App(props) {

  useEffect(() => {

    window.addEventListener('beforeunload', beforeunload);

    // returned function will be called on component unmount 
    return () => {
      window.removeEventListener('beforeunload', beforeunload);
    }
  }, []);

  const beforeunload = (e) => {
    if (props.dataUnsaved) {
      e.preventDefault();
      e.returnValue = true;
    }
  };

  return (
    <div>Hello World</div>
  );
}

注意:如果不使用the second parameter(here is empty),则将在每次组件渲染时调用您的钩子。所以要小心。