加入收藏 | 设为首页 | 会员中心 | 我要投稿 核心网 (https://www.hxwgxz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程 > 正文

effect的更新依赖屈指可数

发布时间:2021-05-25 01:45:30 所属栏目:编程 来源:互联网
导读:useEffect中的第二个参数,可以是一个参数数组(依赖数组)。React更新DOM的思想,不管过程怎样,只将结果展示给世人。 React在更新组件的时候,会对比props,通过
副标题[/!--empirenews.page--]

useEffect中的第二个参数,可以是一个参数数组(依赖数组)。React更新DOM的思想,不管过程怎样,只将结果展示给世人。

React在更新组件的时候,会对比props,通过AST等方式比较,然后仅需更新变化了的DOM。

第二个参数相当于告诉了useEffect,只要我给你的这些参数任中之一发生了改变,你就执行effect就好了。如此,便可以减少每次render之后调用effect的情况,减少了无意义的性能浪费。

那么在开发过程中,我们会尝试在组件载入时候,通过api获取远程数据,并运用于组件的数据渲染,所以我们使用了如下的一个简单例子:

useEffect(() => { 

  featchData(); 

}, []); 

由于是空数组,所以只有在组件挂载(mount)时获取一遍远程数据,之后将不再执行。如果effect中有涉及到局部变量,那么都会根据当前的状态发生改变,函数是每次都会创建(每次都是创建的新的匿名函数)。

function Counter() { 

  const [count, setCount] = useState(0); 

 

  useEffect(() => { 

    const id = setInterval(() => { 

      setCount(count + 1); 

    }, 1000); 

    return () => clearInterval(id); 

  }, []); 

 

  return <h1>{count}</h1>; 

你可能会认为上面的例子,会在组件加载后,每秒UI上count+1,但实际情况是只会执行一次。为什么呐?是不是觉得有些违反直觉了?

因为,并没有给effect的依赖项加入count,effect只会在第一次渲染时候,创建了一个匿名函数,尽管通过了setInterval包裹,每秒去执行count + 1,但是count的值始终是为0,所以在UI表现上永远渲染的是1。

当然,通过一些规则,我们可以通过加上count来改变其值,或者通过useRef,或者通过setState(x => x+1),模式来实现获取最新的值。例如下面的黑科技操作:

// useRef 

function Example() { 

  const [count, setCount] = useState(0); 

  const countRef = useRef(count); 

  countRef.current = count; // 假如这一行代码放到effect函数中会怎么样呐?可以思考下! 

  // answer: 在effect中count是effect匿名函数声明时就有了,值就是0,那么拿到的count值自然也是渲染前(本次props中的值)的count(值为0,再次复盘理解下快照的概念),但由于依赖数组中并不存在任何依赖,所以该匿名函数不会二次执行。 

  // 但,由于setInterval的原因,函数会不停地setCount,关键是其中的参数了,countRef.current = count;取到的值是第一次快照时候的值0,所以其更新的值永远为0+1 = 1。这样的结果是符合预期规则的。 

  // 那为什么放在外面就好了呐?因为countRef.current同步了count的最新值,每次render前就拿到了新的count值,并且赋值给countRef.current,由于ref的同步特性(及时性、统一性),所以循环中获取的countRef.current也是最新的值,故而能实现计数效果 

 

  useEffect(() => { 

    const id = setInterval(() => { 

      setCount(countRef.current + 1); 

    }, 1000); 

    return () => clearInterval(id); 

  }, []); 

 

  return <h1>{count}</h1>; 

 

// setState传入函数 

function Example() { 

  const [count, setCount] = useState(0); 

 

  useEffect(() => { 

    const id = setInterval(() => { 

(编辑:核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读