UseEffect

Effect Hook 可以让你在函数组件中执行副作用操作

提示

如果你熟悉 React class 的生命周期函数,你可以把 useEffect Hook 看做 componentDidMountcomponentDidUpdatecomponentWillUnmount 这三个函数的组合。

执行时机

useEffect在浏览器的重回之后异步执行。

componentDidMountcomponentDidUpdate 不同的是,传给 useEffect 的函数会在浏览器完成布局与绘制之后,在一个延迟事件中被调用。

然而,并非所有 effect 都可以被延迟执行。对于需要同步执行的hooks我们需要使用useLayoutEffect

Effect会保证在任何新的渲染前执行,在开始执行新的Effect CallBack前,总会清除上一轮渲染的Effect

  1. 默认情况,在第一次渲染之后每次更新之后都会执行

    const Effect: React.FC = () => {
      const [value, setValue] = React.useState('');
      React.useEffect(() => {
        document.title = value;
        console.log('value is ', value);
      });
      return (
        <div>
          <h2>Effect</h2>
          <input
            value={value}
            onChange={(e) => setValue(e.target.value)}
            placeholder="document.title" />
        </div>
      );
    };
    
  2. 仅仅在Dom第一次渲染和每次value变化后执行

    React.useEffect(() => {
        console.log('[dep value] value is ', value);
      }, [value]);
    
  3. 仅仅在Dom第一次渲染执行

    React.useEffect(() => {
        console.log('[first render] value is ', value);
      }, []);
    

传入依赖的比较规则

Object.is()

用于判断两个值是否为同一个值

如果满足以下条件则两个值相等:

== (en-US)open in new window 运算不同。 == 运算符在判断相等前对两边的变量(如果它们不是同一类型) 进行强制转换 (这种行为的结果会将 "" == false 判断为 true), 而 Object.is不会强制转换两边的值。

=== (en-US)open in new window 运算也不相同。 === 运算符 (也包括 == 运算符) 将数字 -0+0 视为相等 ,而将Number.NaNopen in new windowNaNopen in new window视为不相等.

// polyfill Object.is
if (!Object.is) {
    Object.is = function(x, y) {
        if (x === y) {
            return x !== 0 || 1/x === 1/y;
        } else {
            return x !== x && y !== y;
        }
    };
}