hook useEffect

2020-12-18  本文已影响0人  曾经也是个少年

useState

  1. 最简单的 useState 用法是这样的:

    function Counter() {
      var [count, setCount] = useState(0);
    
      return (
        <div>
          <div>{count}</div>
          <Button onClick={() => { setCount(count + 1); }}>
            点击
          </Button>
        </div>
      );
    }
    
  2. 基于 useState 的用法,我们尝试着自己实现一个 useState:

    function useState(initialValue) {
      var state = initialValue;
      function setState(newState) {
        state = newState;
        render();
      }
      return [state, setState];
    }
    
  3. 这时我们发现,点击 Button 的时候,count 并不会变化,为什么呢?我们没有存储 state,每次渲染 Counter 组件的时候,state 都是新重置的。

    自然我们就能想到,把 state 提取出来,存在 useState 外面。

```source-js
var _state; // 把 state 存储在外面

function useState(initialValue) {
  _state = _state || initialValue; // 如果没有 _state,说明是第一次执行,把 initialValue 复制给它
  function setState(newState) {
    _state = newState;
    render();
  }
  return [_state, setState];
}
```

到目前为止,我们实现了一个可以工作的 useState,至少现在来看没啥问题。

接下来,让我们看看 useEffect 是怎么实现的。

useEffect

useEffect 是另外一个基础的 Hook,用来处理副作用,最简单的用法是这样的:

 useEffect(() => {
    console.log(count);
 }, [count]);

我们知道 useEffect 有几个特点:

  1. 有两个参数 callback 和 dependencies 数组
  2. 如果 dependencies 不存在,那么 callback 每次 render 都会执行
  3. 如果 dependencies 存在,只有当它发生了变化, callback 才会执行

我们来实现一个 useEffect

let _deps; // _deps 记录 useEffect 上一次的 依赖

function useEffect(callback, depArray) {
  const hasNoDeps = !depArray; // 如果 dependencies 不存在
  const hasChangedDeps = _deps
    ? !depArray.every((el, i) => el === _deps[i]) // 两次的 dependencies 是否完全相等
    : true;
  /* 如果 dependencies 不存在,或者 dependencies 有变化*/
  if (hasNoDeps || hasChangedDeps) {
    callback();
    _deps = depArray;
  }
}
上一篇下一篇

猜你喜欢

热点阅读