📒REACT笔记👉👉👉React-Hooks中的useEffect

React-Hooks已经问世很久了,但也没有在项目中全量地使用(除了useState)。最近看了一篇讲解 useEffect的文章,觉得不错,所以写下来观后感~

我们先从下面的代码开始,如果我们操作如下:

  • 先点击.counter按钮三次,将count增加到3.
  • 然后点击.show-alert按钮.
  • 接着再点击.counter按钮两次,将count增加到5.

过了三秒(因为我们的事件处理函数里是一个3s的延时器),屏幕会弹出来数字几呢?

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
function Counter() {
  const [count, setCount] = React.useState(0);

  const handleAlert = () => {
    setTimeout(() => {
      alert(count);
    }, 3000)
  }

  <p>Count👉 {count}</p>
  <button classname='counter' onClick={() => setCount((preCount) => preCount + 1)}>增加</button>
  <button classname='show-alert' onClick={handleAlert}>弹出来吧!</button>
}

其实是👉3

可能有的人会认为我们的count不是在延时器(setTimeout)执行前已经被增加到数字5了吗?其实不然。 解释这个问题我们首先要有一个共识: setCount函数的执行,让组件重新渲染,组件函数被重新调用。 那handleAlert函数呢?它在每次渲染的过程中,其实也是一个新的函数,它函数体内的代码如果引用到了 state或者props,只会记住它那次渲染过程里的stateprops,而不是最新的stateprops。 原理是什么呢?是有什么watcher特性吗?还是什么魔法。都不对,是闭包,听到闭包这两个字是不是虎躯一震? 我们可以用另一段代码来演示这个特性:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
const obj = {
  count: 0;
}

const sayCount = (obj) => {
  const count = obj.count;
  setTimeout(() => {
    alert(count);
  }, 3000);
}

sayCount(obj);

obj.count = 1;

sayCount(obj);

obj.count = 2;

sayCount(obj);

这面这一段代码执行以后会一次弹出0, 1, 2。因为每一个延时器通过闭包记住函数内的定义它的那次中的本地变量👉count。

未完待续.....

updatedupdated2020-07-062020-07-06