在React的官方文档中提到了-
如果你熟悉React类的生命周期方法,你可以思考 将useEffect钩子作为componentDidMount, componentDidUpdate和 componentWillUnmount总和。
我的问题是-我们如何在钩子中使用componentWillMount()生命周期方法?
在React的官方文档中提到了-
如果你熟悉React类的生命周期方法,你可以思考 将useEffect钩子作为componentDidMount, componentDidUpdate和 componentWillUnmount总和。
我的问题是-我们如何在钩子中使用componentWillMount()生命周期方法?
当前回答
这可能不是componentWillMount方法的确切替代方法,但这里有一个方法可以用来实现同样的目标,但要使用useEffect:
首先初始化检索数据的对象为空值,并定义useEffect方法:
const [details, setDetails] = useState("")
useEffect(() => {
retrieveData();
}, []);
const retrieveData = () => {
getData() // get data from the server
.then(response => {
console.log(response.data);
setDetails(response.data)
})
.catch(e => {
console.log(e);
})
}
在JSX中,我们返回一个三元操作符
*return(
<div>
{
details ? (
<div class="">
<p>add Your Jsx Here</p>
</div>
): (
<div>
<h4>Content is still Loading.....</h4>
</div>
)
}
</div>
)*
这将确保在对象'details'中有数据之前,terenary操作符的第二部分会被加载,该操作符会触发useEffect方法,该方法导致在'details'对象中设置从服务器接收到的数据,从而呈现主JSX
其他回答
本·卡普的答案对我来说似乎是唯一有效的答案。
但由于我们使用的是函数式方法,另一种方法可以受益于闭包和HoC:
const InjectWillmount = function(Node, willMountCallback) {
let isCalled = true;
return function() {
if (isCalled) {
willMountCallback();
isCalled = false;
}
return Node;
};
};
然后使用它:
const YourNewComponent = InjectWillmount(<YourComponent />, () => {
console.log("your pre-mount logic here");
});
useComponentWillMount钩
const useComponentWillMount = (cb) => {
const willMount = useRef(true)
if (willMount.current) cb()
willMount.current = false
}
当出现顺序问题(比如在另一个脚本之前运行)时,这个钩子可以作为一个保护程序。如果不是这样,请使用useComnponentDidMount,它更符合React钩子的范例。
useComponentDidMount钩
const useComponentDidMount = cb => useEffect(cb, []);
如果你知道你的效果应该只运行一次在开始使用这个解决方案。它只会在组件挂载后运行一次。
useEffect范式
类组件具有生命周期方法,这些方法定义为组件时间轴上的点。钩子不遵循这种范式。相反,效果应该由内容构成。
function Post({postID}){
const [post, setPost] = useState({})
useEffect(()=>{
fetchPosts(postID).then(
(postObject) => setPost(postObject)
)
}, [postID])
...
}
在上面的例子中,效果处理的是获取文章的内容。而不是一个特定的时间点,它有一个它所依赖的值- postID。每次postID得到一个新值(包括初始化),它都会重新运行。
组件将挂载讨论
在类组件中,componentWillMount被认为是遗留的(源1,源2)。它是遗留的,因为它可能运行不止一次,而且还有另一种选择——使用构造函数。这些考虑因素与功能组件无关。
我们最近遇到了这个问题,因为我们需要在组件挂载时做一些事情,也就是我们需要更新全局状态。
所以我创建了这个钩子,不确定这个方法有多好,但到目前为止,只要我们少用它,只用于简单的任务,它就能工作。我可能不会将它用于网络请求和其他长时间运行的复杂任务。
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;
钩子中的React生命周期方法
为了简单的视觉参考,请遵循此图像
正如您在上图中所看到的,对于ComponentWillUnmount,您必须这样做
useEffect(() => {
return () => {
console.log('componentWillUnmount');
};
}, []);
正如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中返回一个函数,如上所述。