在React的官方文档中提到了-
如果你熟悉React类的生命周期方法,你可以思考 将useEffect钩子作为componentDidMount, componentDidUpdate和 componentWillUnmount总和。
我的问题是-我们如何在钩子中使用componentWillMount()生命周期方法?
在React的官方文档中提到了-
如果你熟悉React类的生命周期方法,你可以思考 将useEffect钩子作为componentDidMount, componentDidUpdate和 componentWillUnmount总和。
我的问题是-我们如何在钩子中使用componentWillMount()生命周期方法?
当前回答
我们最近遇到了这个问题,因为我们需要在组件挂载时做一些事情,也就是我们需要更新全局状态。
所以我创建了这个钩子,不确定这个方法有多好,但到目前为止,只要我们少用它,只用于简单的任务,它就能工作。我可能不会将它用于网络请求和其他长时间运行的复杂任务。
import { useRef } from 'react';
function useComponentWillMount(callback: () => void) {
const hasMounted = useRef(false);
if (!hasMounted.current) {
(() => {
hasMounted.current = true;
callback();
})();
}
console.log(hasMounted.current);
return null;
}
export default useComponentWillMount;
其他回答
你不能在钩子中使用任何现有的生命周期方法(componentDidMount, componentDidUpdate, componentWillUnmount等)。它们只能在类组件中使用。而Hooks只能用于功能组件。下面这句话来自React文档:
如果你熟悉React类的生命周期方法,你可以把useEffect Hook看作componentDidMount、componentDidUpdate和componentWillUnmount的组合。
建议是,可以在功能组件中从类组件中模拟这些生命周期方法。
componentDidMount中的代码在组件挂载时运行一次。useEffect钩子等价于此行为是
useEffect(() => {
// Your code here
}, []);
注意这里的第二个参数(空数组)。这将只运行一次。
如果没有第二个参数,useEffect钩子将在组件的每次渲染时被调用,这可能是危险的。
useEffect(() => {
// Your code here
});
componentWillUnmount用于清理(比如删除事件监听器,取消定时器等)。假设您正在componentDidMount中添加一个事件侦听器,并在componentWillUnmount中删除它,如下所示。
componentDidMount() {
window.addEventListener('mousemove', () => {})
}
componentWillUnmount() {
window.removeEventListener('mousemove', () => {})
}
与上述代码等价的钩子如下所示
useEffect(() => {
window.addEventListener('mousemove', () => {});
// returned function will be called on component unmount
return () => {
window.removeEventListener('mousemove', () => {})
}
}, [])
钩子中的React生命周期方法
为了简单的视觉参考,请遵循此图像
正如您在上图中所看到的,对于ComponentWillUnmount,您必须这样做
useEffect(() => {
return () => {
console.log('componentWillUnmount');
};
}, []);
对你最初的问题的简短回答,componentWillMount如何与React Hooks一起使用:
componentWillMount已弃用,被认为是遗留的。反应推荐:
通常,我们建议使用构造函数()来初始化状态。
现在,在Hook FAQ中,你会发现函数组件的类构造函数的等价是:
构造函数:函数组件不需要构造函数。你可以在useState调用中初始化这个状态。如果计算初始状态的开销很大,您可以将一个函数传递给useState。
componentWillMount的用法示例如下所示:
const MyComp = () => {
const [state, setState] = useState(42) // set initial value directly in useState
const [state2, setState2] = useState(createInitVal) // call complex computation
return <div>{state},{state2}</div>
};
const createInitVal = () => { /* ... complex computation or other logic */ return 42; };
正如react文档中所述:
您可能会认为我们需要一个单独的效果来执行 清理。但是添加和删除订阅的代码非常紧凑 useEffect的设计是为了将它们放在一起。如果你的效果 返回一个函数,React会在清理的时候运行它:
useEffect(() => {
function handleStatusChange(status) {
setIsOnline(status.isOnline);
}
ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
// Specify how to clean up after this effect:
return function cleanup() {
ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
};
});
if (isOnline === null) {
return 'Loading...';
}
return isOnline ? 'Online' : 'Offline';
}
所以我们唯一需要在钩子中使用componentWillUnmount的是在useEffect中返回一个函数,如上所述。
componentWillMount已弃用(正如在其他评论中提到的),原因是我认为它很容易被一个简单的HOC处理。
const withComponentWillMount = (WrappedComponent, handler) => {
return (props) => {
return handler(props) ? <WrappedComponent {...props} /> : null;
}
}
我通常在我的项目中实现这个解决方案。使用此HOC,如果处理程序返回false,则组件内部不运行任何内容,包括钩子。