我试图深入了解useEffect
钩子。
我想知道何时使用哪种方法以及为什么?
- 使用效果,没有第二个参数
useEffect(()=>{})
- useEffect,第二个参数作为
[]
useEffect(()=>{},[])
- useEffect,在第二个参数中传递了一些参数
useEffect(()=>{},[arg])
useEffect(callback);
// Example
useEffect(() => {
console.log("executed after render phase");
return () => {
console.log("cleanup function after render");
};
});
- 在每个组件渲染上运行。
- 通常用于调试,类似于函数在每个 呈现:
const Component = () => {
callback()
return <></>;
};
注意:执行时间仍然存在差异(请参阅下一条注释(。检查此沙盒日志。
- 清理函数在每次渲染后运行。
useEffect(callback,[]);
// Example
useEffect(() => {
const fetchUsers = async () => {
const users = await fetch();
setUsers(users);
};
fetchUsers();
console.log("called on component's mount");
return () => {
console.log("called on component's unmount");
};
}, []);
- 通常用于通过数据获取等初始化组件状态。
- 在组件装载上运行一次。
- 清理功能将在组件卸载时运行。
陷阱:
- 在渲染阶段之后执行的回调。
请记住,首先是渲染,然后是坐骑。
- 由于关闭而导致数据过时
粗略地说,大多数关于
useEffect
的错误都不知道闭包是如何工作的,也没有注意linting 警告。
<小时 />确保数组包含组件范围内随时间变化并由效果使用的所有值。否则,您的代码将引用以前渲染中的过时值- React 文档中的注释。
useEffect(callback,[arg]);
// Example
useEffect(() => {
console.log({ users });
return () => {
console.log("user value is changing");
};
}, [users]);
- 在更改
arg
值时运行。 - 通常用于在道具/状态更改上运行事件。
- 可以提供多个依赖项:
[arg1,arg2,arg3...]
- 清理函数在值更改
arg
运行。
陷阱:
- "变化时">是指与之前的
arg
值进行浅层比较。
即比较来自上一个渲染和当前渲染的
arg
值,prevArg === arg ? doNothing() : callback()
.
因为在 Javascript 中
{} === {} || [] === []
是一个虚假语句,如果arg
(在我们的示例中users
(是一个对象,回调将在每次渲染上运行。也可以在mount上运行,因为第一次比较总是假的
额外须知要点
useEffect
浏览器重新绘制后触发的回调。useEffect
按声明顺序执行的回调(就像所有钩子一样(,请检查示例。- 每个
useEffect
都应该有一个单一的责任。 - 如果使用
useRef
中的值,请在清理函数中事先将该值复制到回调的作用域。
const timeoutIdRef = useRef();
useEffect(() => {
const timeoutId = timeoutIdRef.current;
return () => {
/*
Using timeoutIdRef.current directly here is not safe
since you can't guarantee the ref to exists in this point
(especially when the component unmounts)
*/
// Should get a lint warning here
clearTimeout(timeoutIdRef.current); // BAD
// Closure on timeoutId value
clearTimeout(timeoutId); // GOOD
};
}, [arg]);
- 当 ref 指向 DOM 元素时,使用
ref.current
作为useEffect
的依赖项是否安全? - 有时您需要在挂载或首次渲染时运行
useEffect
一次,这些是常见的模式。
const isMounted = useRef(false);
useEffect(() => {
if (isMounted.current) {
// first mount
} else {
isMounted.current = true;
}
}, [arg]);
<小时 />继续阅读:
- 我的附加答案解释了
useEffect
回调的return
语句 - 丹·阿布拉莫夫的
useEffect
完整指南 useEffect
接口- 使用效果钩子 - React 文档
如果你熟悉 React 类生命周期方法,你可以将 useEffect Hook 视为 componentDidMount、componentDidUpdate 和 componentWillUnmount 的组合。
1.useEffect没有第二个参数:当我们希望在组件刚刚挂载或更新时发生某些事情时使用。 从概念上讲,我们希望它在每次渲染后发生。
2.useEffect,第二个参数为[]:当我们希望在安装组件时发生某些事情时使用,如果在挂载时只执行一次。它更接近熟悉的组件DidMount和componentWillUnmount。
3.useEffect,在第二个参数中传递了一些参数:当我们希望在 pramter 通过时发生某些事情时使用,例如。 在您的情况下,参数已更改。
欲了解更多信息,请查看此处:https://reactjs.org/docs/hooks-effect.html