useEffect 懒创建清理函数
useEffect lazy created cleanup function
我正在尝试创建使用副作用函数 returns 清除回调的效果的挂钩。但是我只想在卸载组件时调用它,而不是在重新渲染时调用它。
使用空 deps 数组调用 useEffect 时的常规方法在这里不起作用,因为清理函数仅在第一次调用挂钩时创建一次。但是我的清理是后来创建的,所以没有办法改变它。
function useListener(data) {
const [response, updateResponse] = useState(null);
useEffect(
() => {
if (data) {
const removeListener = callRequest(data, resp => {
updateResponse(resp);
});
return removeListener;
}
},
[data]
);
return response;
}
这归结为以下问题:在正常的 class 组件中,willComponentUnmount
可以根据当前组件状态做出决定,但在 useEffect 的情况下,状态通过闭包传递给清理,如果状态已更改,以后将无法传递信息
您可以使用useRef
保存和更新您的回调函数
The useRef() Hook isn’t just for DOM refs. The “ref” object is a generic container whose current property is mutable and can hold any value, similar to an instance property on a class. more
function useListener(data) {
const [response, updateResponse] = useState(null);
const cleanUpCallbackRef = useRef(() => {});
useEffect(
() => {
if (data) {
cleanUpCallbackRef.current = callRequest(data, resp => {
updateResponse(resp);
});
}
},
[data]
);
useEffect(() => {
return () => {
cleanUpCallbackRef.current();
}
}, []);
return response;
}
我创建一个简单的例子here
我正在尝试创建使用副作用函数 returns 清除回调的效果的挂钩。但是我只想在卸载组件时调用它,而不是在重新渲染时调用它。
使用空 deps 数组调用 useEffect 时的常规方法在这里不起作用,因为清理函数仅在第一次调用挂钩时创建一次。但是我的清理是后来创建的,所以没有办法改变它。
function useListener(data) {
const [response, updateResponse] = useState(null);
useEffect(
() => {
if (data) {
const removeListener = callRequest(data, resp => {
updateResponse(resp);
});
return removeListener;
}
},
[data]
);
return response;
}
这归结为以下问题:在正常的 class 组件中,willComponentUnmount
可以根据当前组件状态做出决定,但在 useEffect 的情况下,状态通过闭包传递给清理,如果状态已更改,以后将无法传递信息
您可以使用useRef
保存和更新您的回调函数
The useRef() Hook isn’t just for DOM refs. The “ref” object is a generic container whose current property is mutable and can hold any value, similar to an instance property on a class. more
function useListener(data) {
const [response, updateResponse] = useState(null);
const cleanUpCallbackRef = useRef(() => {});
useEffect(
() => {
if (data) {
cleanUpCallbackRef.current = callRequest(data, resp => {
updateResponse(resp);
});
}
},
[data]
);
useEffect(() => {
return () => {
cleanUpCallbackRef.current();
}
}, []);
return response;
}
我创建一个简单的例子here