你不知道的useEffect

定义

function useEffect(effect: EffectCallback, deps?: DependencyList): void;
 
type DependencyList = ReadonlyArray<any>;
 
type EffectCallback = () => (void | (() => void | undefined));

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

什么是副作用?

函数式编程的特点

  • 函数是"第一等公民":函数与其他数据类型一样,处于平等地位,可以赋值给其他变量,也可以作为参数,传入另一个函数,或者作为别的函数的返回值。
  • 只用"表达式",不用"语句":“表达式”(expression)是一个单纯的运算过程,总是有返回值;“语句”(statement)是执行某种操作,没有返回值。
  • 函数式编程要求,只使用表达式,不使用语句。也就是说,每一步都是单纯的运算,而且都有返回值。
  • 没有"副作用":所谓"副作用"(side effect),指的是函数内部与外部互动(最典型的情况,就是修改全局变量的值),产生运算以外的其他结果。函数式编程强调没有"副作用",意味着函数要保持独立,所有功能就是返回一个新的值,没有其他行为,尤其是不得修改外部变量的值。
  • 不修改状态:函数式编程只是返回新的值,不修改系统变量。
  • 引用透明性:函数程序通常还加强引用透明性,即如果提供同样的输入,那么函数总是返回同样的结果。

哪些操作属于副作用操作?

数据获取,设置订阅, 更改DOM等行为。

使用

import React, {
      useState, useEffect } from 'react';
function Example() {
     
  const [count, setCount] = useState(0);
 
  // Similar to componentDidMount and componentDidUpdate:
  useEffect(() => {
     
    document.title = `You clicked ${
       count} times`;
  });
 
  return (
    <div>
      <p>You clicked {
     count} times</p>
      <button onClick={
     () => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

注意事项

  • 默认情况下,它在第一次渲染之后和每次更新之后都会执行
  • 有些副作用需要清除
useEffect(() => {
     
  const handleResize = () => {
     
    console.log(`count is ${
       count}`);
  };
  window.addEventListener("resize", handleResize);
  // 如果不返回清除函数,会导致重复注册监听事件
  return () => window.removeEventListener("resize", handleResize);
});
  • 在 effect 中使用的变量需要加到 useEffect 的第二个参数中。
useEffect(() => {
     
  const handleResize = () => {
     
    console.log(`count is ${
       count}`);
  };
  window.addEventListener("resize", handleResize);
  return () => window.removeEventListener("resize", handleResize);
  // 如果count不加入到第二个参数中,后续监听不到count的变化,输出的永远都是初始化的count值。
  // 如果不传第二个参数,每一次render都会调用useEffect方法。
}, [count]);
  • 把条件判断放在useEffect内部
const [count, setCount] = useState(0);
 
const handleResize = () => {
     
  console.log(`count is ${
       count}`);
};
 
// 错误:React Hooks must be called in the exact same order in every component render
if (count > 0) {
     
  useEffect(() => {
     
    window.addEventListener("resize", handleResize);
    return () => window.removeEventListener("resize", handleResize);
  }, [count]);
}

你可能感兴趣的:(前端开发,React,前端,reactjs)