前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >react Hook初探

react Hook初探

作者头像
theanarkh
发布2019-04-24 11:02:44
5920
发布2019-04-24 11:02:44
举报
文章被收录于专栏:原创分享原创分享

文章的代码来自https://www.cnblogs.com/qcloud1001/p/10408634.html。

下面是对这个代码以及react hook的分析。二话不说,直接上代码。

代码语言:javascript
复制
import React, { useState, useEffect, useRef } from 'react';export default function App() {  console.log(1)  let [count, setCount] = useState(0);  useInterval(() => {    // Your custom logic here    setCount(count + 1);  }, 1000);

  return <h1>{count}</h1>;}var ref = nullfunction useInterval(callback, delay) {  console.log(2)  const savedCallback = useRef();  if (ref) {    console.log(ref===savedCallback)  } else {    ref = savedCallback;  }  // Remember the latest callback.  useEffect(() => {    console.log(3)    savedCallback.current = callback;  });

  // Set up the interval.  useEffect(() => {    console.log(4)    function tick() {      savedCallback.current();    }    if (delay !== null) {      let id = setInterval(tick, delay);      return () => clearInterval(id);    }  }, [delay]);}

我们执行这个代码发现,输出是1,2,3,4,1,2,true,3,1,2,true,3。首先可以发现useRef每次执行的时候返回的都是一样的值。下面我们分析一下整个流程,第一个执行的时候,输出1,2,是很好理解的。然后在render结束后,会执行两个effect里的回调。所以输出了3,4也是可以理解的。执行完4之后开启了一个定时器。每隔一段时间定时器的回调就会执行,回调函数更新了state,从而导致re-render,每次re-render的时候,首先输出1,然后又重新执行了useInterval函数,所以输出2,重新设置了两个effect的回调,因为第一个effect没有设置第二个参数,所以每次re-render都会执行,所以输出3.但是第二个effect依赖于delay的改变,但是delay没有改变,所以他没有执行。所以没有输出4,对于第二个effect,重新设置了回调是为了保证拿到闭包里的参数是最新的,但是react保存的destroy函数,即effect回调执行时返回的函数。是第一次render的时候返回的那个。后面的re-render同理。

下面再看文章中的另一个例子。

代码语言:javascript
复制
import React, { useState, useEffect, useRef } from 'react';export default function App() {  console.log(1)  let [count, setCount] = useState(0);  let [delay, setDelay] = useState(1000);

  useInterval(() => {    // Your custom logic here    setCount(count + 1);  }, delay);

  function handleDelayChange(e) {    setDelay(Number(e.target.value));  }



  return [<h1>{count}</h1>,<input value={delay} onChange={handleDelayChange} />];}var ref = null;function useInterval(callback, delay) {  console.log(2)  const savedCallback = useRef();  if (ref) {    console.log(ref === savedCallback)  } else {    ref = savedCallback;  }  // Remember the latest callback.  useEffect(() => {    console.log(3)    savedCallback.current = callback;  });

  // Set up the interval.  useEffect(() => {    console.log(4)    function tick() {      savedCallback.current();    }    if (delay !== null) {      let id = setInterval(tick, delay);      return () => clearInterval(id);    }  }, [delay]);}

执行上面的例子,和第一个一样,但是如果我们手动输入一个值的时候,会发现多输出了一个4。这是两个例子的区别,因为第二个effect依赖的delay改变了,所以他会首先执行前一个effect回调返回的destroy函数,清理了前一个定时器,然后重新设置了回调,并且执行了他。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-04-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 编程杂技 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档