react hook useEffect

useEffect 在重新渲染之后执行

数据变化会触发重新渲染

import React, { useState, useEffect } from "react";

export default () => {
  const [str, setStr] = useState("init");
  useEffect(() => {
    console.log("====1",str);
    setStr(+new Date());   // 会造成死循环, 无限刷新
    console.log("====2",str);
  },
  []        // 强行只执行一次
  );

  return <div>{str}</div>;
};

 

出现死循环的原因:

第一次载入页面str为init, 渲染完成执行effect, 设置str后由于数据不一致, 页面重新渲染, 渲染完成后又重新赋值, 循环往复

设置依赖数组为空数组, 保证只执行一次, 页面中数据为时间戳, 但是set函数并非立即起效, 而是将更新推入更新队列中, 所以两次打出的都是初始值

 

 

依赖数组和返回的卸载函数

依赖数组中的数据变化才会执行effect, 并且该effect返回的函数, 会在组件卸载的时候调用

import React, { useState, useEffect } from "react";

export default () => {
  const [time, setTime] = useState(+new Date());
  const [count1, setCount1] = useState(0);
  const [count2, setCount2] = useState(0);

  useEffect(() => {
    console.log("refresh", count1, count2);
    setTime(+new Date());
    return () => {
      console.log("unmount");
    };
  }, [count1]);

  const add1 = () => {
    setCount1((c) => c + 1);
  };
  const add2 = () => {
    setCount2((c) => c + 1);
  };
  return (
    <div>
      <div>count1: {count1}</div>
      <div>count2: {count2}</div>
      <div>time: {time}</div>
      <button onClick={add1}>add1</button>
      <button onClick={add2}>add2</button>
    </div>
  );
};

 

闭包导致的修改数据失败问题, 使用函数修改数据

import React, { useState, useEffect } from "react";

export default () => {
  const [count, setCount] = useState(0);

  useEffect(() => {
    const id = setInterval(() => {
        setCount((count) => count + 1);

        // 下面的写法会导致count永远是1
        // 因为函数闭包中的count是初次渲染的值 
        // setCount( count + 1 );
    }, 100);

    return () => clearInterval(id);
  }, []);
  return <div>{count}</div>;
};

 

 

异步取值, 无法取到最新值, 使用ref

点击show, 然后点击add, 几秒后, 输出如下,  可以看到count的值并不是最新的 , 只能使用ref保存一个副本, 但这么做很不优雅, 且目前好像没有其他解决办法

import React, { useState, useEffect, useCallback, useRef } from "react";

export default () => {
  const [count, setCount] = useState(0);

  // 修改ref的变量值, 不会触发重新渲染!!!
  const ref = useRef(count);
  ref.current = count;

  const add = () => {
    setCount((c) => c + 1);
  };
  const f = () => {
    console.log("f", count, ref.current);
  };
  const show = () => {
    console.log("show", count, ref.current);
    setTimeout(f, 2000);
  };
  return (
    <div>
      count: {count}
      <button onClick={add}>add</button>
      <button onClick={show}>show</button>
    </div>
  );
};

 

hmoban主题是根据ripro二开的主题,极致后台体验,无插件,集成会员系统
自学咖网 » react hook useEffect