如何使用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,您的效果不依赖于道具或状态的任何值,因此它不需要重新运行。
但是在这种情况下,我依赖道具...但仅用于清理部分...
答案 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>;
}
但是,更好的方法是将第二个参数传递给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]);