深入反应 useEffect/useEffect 的使用? [英] React useEffect in depth / use of useEffect?

查看:32
本文介绍了深入反应 useEffect/useEffect 的使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试深入了解 useEffect 钩子.

我想知道何时使用哪种方法以及为什么?

1.useEffect 没有第二个参数useEffect(()=>{})2.useEffect 的第二个参数为 []useEffect(()=>{},[])3.useEffect 在第二个参数中传递一些参数useEffect(()=>{},[arg])

解决方案

useEffect(callback);//例子useEffect(() => {console.log(渲染阶段后执行");返回 () =>{console.log(渲染后的清理功能");};});

  • 每个组件渲染上运行.
  • 通常用于调试,类似于函数体在每个渲染:

const Component = () =>{打回来()返回<></>;};

<块引用>

注意:在执行时间方面仍然存在差异(请参阅下一个注意事项).检查这个沙箱日志.


useEffect(callback,[]);//例子useEffect(() => {const fetchUsers = async() =>{const 用户 = 等待 fetch();设置用户(用户);};fetchUsers();console.log(调用组件的挂载");返回 () =>{console.log(调用组件的卸载");};}, []);

  • 通常用于通过数据获取等方式初始化组件状态
  • 在组件安装上运行一次.
  • 清理功能将在组件的卸载.

问题:

<块引用>

记住,有一个第一次渲染,然后然后一个坐骑.

<块引用>

粗略地说,大多数关于 useEffect 的错误是不知道闭包是如何工作的,并且没有注意linting警告.

<块引用>

确保数组包含组件范围内的所有值,这些值随时间变化并被效果使用.否则,您的代码将引用之前渲染中的陈旧值 - React 文档中的注释.


useEffect(callback,[arg]);//例子useEffect(() => {控制台日志({用户});返回 () =>{console.log(用户值正在改变");};}, [用户]);

  • arg 值变化时运行.
  • 通常用于在道具/状态更改时运行事件.
  • 可以提供多个依赖:[arg1,arg2,arg3...]
  • 清理函数在 arg 值更改时运行.

问题:

  • On Change" 指的是 浅比较arg 的前一个值.
<块引用>

i.e 比较来自前一个渲染和当前渲染的 arg 的值,prevArg === arg ?doNothing() : callback().

  • 因为在 Javascript {} === {} ||[] === [] 是一个 falsy 语句,如果 arg(在我们的示例中为 users)是一个对象,则回调将在每次渲染时运行.

  • 也在挂载上运行,因为第一次比较总是错误的


其他注意事项

const timeoutIdRef = useRef();useEffect(() => {const timeoutId = timeoutIdRef.current;返回 () =>{/*在这里直接使用 timeoutIdRef.current 是不安全的因为你不能保证在这一点上存在引用(特别是当组件卸载时)*///应该在这里得到一个 lint 警告clearTimeout(timeoutIdRef.current);//坏的//关闭 timeoutId 值clearTimeout(timeoutId);//好的};}, [参数]);

const isMounted = useRef(false);useEffect(() => {如果(isMounted.current){//第一次挂载} 别的 {isMounted.current = true;}}, [参数]);


继续阅读:

I am trying to understand the useEffect hook in-depth.

I would like to know when to use which method and why?

1.useEffect with no second paraments
 useEffect(()=>{})

2.useEffect with second paraments as []
  useEffect(()=>{},[])

3.useEffect with some arguments passed in the second parameter
 useEffect(()=>{},[arg])

解决方案

useEffect(callback);

// Example
useEffect(() => {
  console.log("executed after render phase");

  return () => {
    console.log("cleanup function after render");
  };
});

  • Runs on every component render.
  • Typically used for debugging, analogous to function's body execution on every render:

const Component = () => {
  callback()
  return <></>;
};

Note: There is still a difference, in execution time (see the next note). Check this sandbox logs.


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");
  };
}, []);

  • Usually used for initializing components state by data fetching etc.
  • Runs once on a component mount.
  • The cleanup function will run on component's unmount.

Gotchas:

Remember, there is a first render and then a mount.

Roughly saying, most of bugs regarding useEffect is not knowing how closures works and not paying attention to linting warnings.

Make sure the array includes all values from the component scope that change over time and that are used by the effect. Otherwise, your code will reference stale values from previous renders - note in React docs.


useEffect(callback,[arg]);

// Example
useEffect(() => {
  console.log({ users });

  return () => {
    console.log("user value is changing");
  };
}, [users]);

  • Runs on change of arg value.
  • Usually used to run events on props/state change.
  • Multiple dependencies can be provided: [arg1,arg2,arg3...]
  • The cleanup function runs on arg value change.

Gotchas:

i.e compares the value of arg from the previous render and the current one, prevArg === arg ? doNothing() : callback().

  • Because in Javascript {} === {} || [] === [] is a falsy statement, if arg (users in our example) is an object, the callback will run on every render.

  • Runs on mount too, since the first comparison always falsy


Additional Good to Know Points

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]);

const isMounted = useRef(false);

useEffect(() => {
  if (isMounted.current) {
    // first mount
  } else {
    isMounted.current = true;
  }
}, [arg]);


Keep reading:

这篇关于深入反应 useEffect/useEffect 的使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆