useEffect React钩子将在每次更改时运行传入函数。可以对其进行优化,使其仅在所需属性更改时调用。
如果我想从componentDidMount调用初始化函数,而不是在更改时再次调用它,该怎么办?假设我想加载一个实体,但加载函数不需要来自组件的任何数据。我们如何使用useEffect钩子来实现这个?
class MyComponent extends React.PureComponent {
componentDidMount() {
loadDataOnlyOnce();
}
render() { ... }
}
如果使用钩子,可能是这样的:
function MyComponent() {
useEffect(() => {
loadDataOnlyOnce(); // this will fire on every change :(
}, [...???]);
return (...);
}
我在网上花了一段时间后发现的。useEffect在组件挂载时触发一次,然后组件卸载并再次挂载,useEffect再次触发。你得多看看React文档,他们为什么这么做。
我使用了自定义钩子。卸载时,你必须改变你的useRef状态。在这种情况下,不要忘记返回语句:当组件卸载时,useEffect在返回后运行清理函数。
import React, { useEffect, useRef } from "react"
const useDidMountEffect = (
func: () => void,
deps: React.DependencyList | undefined
) => {
const didMount = useRef(false)
useEffect(() => {
if (didMount.current) {
func()
}
return () => {
didMount.current = true
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, deps)
}
export default useDidMountEffect
使用它像正常的useEffect:
useDidMountEffect(() => {
// your action
}, [])
function useOnceCall(cb, condition = true) {
const isCalledRef = React.useRef(false);
React.useEffect(() => {
if (condition && !isCalledRef.current) {
isCalledRef.current = true;
cb();
}
}, [cb, condition]);
}
并利用它。
useOnceCall(() => {
console.log('called');
})
or
useOnceCall(()=>{
console.log('Fetched Data');
}, isFetched);
useMountEffect钩
在组件挂载后只运行一次函数是一种非常常见的模式,因此需要使用自己的钩子来隐藏实现细节。
const useMountEffect = (fun) => useEffect(fun, [])
在任何功能组件中使用它。
function MyComponent() {
useMountEffect(function) // function will run only once after it has mounted.
return <div>...</div>;
}
关于useMountEffect钩子
当使用useEffect和第二个数组参数时,React将在挂载(初始渲染)和数组中的值发生变化后运行回调。因为我们传递了一个空数组,所以它只会在挂载之后运行。