具有React useEffect的componentWillUnmount

时间:2019-03-13 10:17:00

标签: javascript reactjs react-hooks react-lifecycle

如何使用useEffect钩子(或与此相关的任何其他钩子)复制componentWillUnmount

在传统的类组件中,我将执行以下操作:

class Effect extends React.PureComponent {
    componentDidMount() { console.log("MOUNT", this.props); }
    componentWillUnmount() { console.log("UNMOUNT", this.props); }
    render() { return null; }
}

使用useEffect钩子:

function Effect(props) {
  React.useEffect(() => {
    console.log("MOUNT", props);

    return () => console.log("UNMOUNT", props)
  }, []);

  return null;
}

(完整示例:https://codesandbox.io/s/2oo7zqzx1n

这是行不通的,因为useEffect中返回的“ cleanup”函数捕获的是道具在安装过程中的状态,而不是在拆卸过程中的状态。

我如何在useEffect中清理最新版本的道具,而不必在每次道具更改时都运行功能主体(或清理)?

类似的question不能解决使用最新道具的问题。

react docs状态:

  

如果要运行效果并仅将其清理一次(在挂载和卸载时),则可以将空数组([])作为第二个参数传递。这告诉React,您的效果不依赖于道具或状态的任何值,因此它不需要重新运行。

但是在这种情况下,我依赖道具...但仅用于清理部分...

3 个答案:

答案 0 :(得分:5)

您可以利用useRef并将要使用的道具存储在闭包中,例如render useEffect返回回调方法

function Home(props) {
  const val = React.useRef();
  React.useEffect(
    () => {
      val.current = props;
    },
    [props]
  );
  React.useEffect(() => {
    return () => {
      console.log(props, val.current);
    };
  }, []);
  return <div>Home</div>;
}

DEMO

但是,更好的方法是将第二个参数传递给useEffect,以便在所需道具的任何更改时进行清理和初始化

React.useEffect(() => {
  return () => {
    console.log(props.current);
  };
}, [props.current]);

答案 1 :(得分:2)

useLayoutEffect() 是你在 2021 年的答案

useLayoutEffect(() => {
    return () => {
        // Your code here.
    }
}, [])

这相当于 ComponentWillUnmount。

99% 的情况下您想使用 useEffect,但如果您想在卸载 DOM 之前执行任何操作,那么您可以使用我提供的代码。

答案 2 :(得分:0)

useEffect(() => {
  if (elements) {
    const cardNumberElement =
      elements.getElement('cardNumber') ||  // check if we already created an element
      elements.create('cardNumber', defaultInputStyles); // create if we did not
            
    cardNumberElement.mount('#numberInput');
  }
}, [elements]);
相关问题