在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;
其他回答
我写了一个自定义钩子,它将在第一次渲染之前运行一个函数。
useBeforeFirstRender.js
import { useState, useEffect } from 'react'
export default (fun) => {
const [hasRendered, setHasRendered] = useState(false)
useEffect(() => setHasRendered(true), [hasRendered])
if (!hasRendered) {
fun()
}
}
用法:
import React, { useEffect } from 'react'
import useBeforeFirstRender from '../hooks/useBeforeFirstRender'
export default () => {
useBeforeFirstRender(() => {
console.log('Do stuff here')
})
return (
<div>
My component
</div>
)
}
useLayoutEffect可以用一个空的观察者集([])来完成这一点,如果功能实际上类似componentWillMount——它将在第一个内容到达DOM之前运行——尽管实际上有两个更新,但它们在绘制到屏幕之前是同步的。
例如:
function MyComponent({ ...andItsProps }) {
useLayoutEffect(()=> {
console.log('I am about to render!');
},[]);
return (<div>some content</div>);
}
与useState相比,使用初始化器/setter或useEffect的好处是,尽管它可以计算一个渲染传递,但用户不会注意到DOM的实际重新渲染,并且它是在第一次明显的渲染之前运行的,而useEffect则不是这样。缺点当然是在你的第一次渲染中有轻微的延迟,因为在绘制到屏幕之前必须进行检查/更新。不过,这确实取决于您的用例。
我个人认为,useMemo在一些特定的情况下是很好的,当你需要做一些沉重的事情时——只要你记住这是例外与规范。
对你最初的问题的简短回答,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; };
componentWillMount已弃用(正如在其他评论中提到的),原因是我认为它很容易被一个简单的HOC处理。
const withComponentWillMount = (WrappedComponent, handler) => {
return (props) => {
return handler(props) ? <WrappedComponent {...props} /> : null;
}
}
我通常在我的项目中实现这个解决方案。使用此HOC,如果处理程序返回false,则组件内部不运行任何内容,包括钩子。
本·卡普的答案对我来说似乎是唯一有效的答案。
但由于我们使用的是函数式方法,另一种方法可以受益于闭包和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");
});