react151618刷新几次的问题

结论:

16 hooks版本

默认render1次

同步中,无论多少种类还是次数,都render 1次。

异步中,无论多少种类还是次数,1个种类执行1次,多次的话,用n*2。

18 hooks版本

默认render2次,

同步中,无论多少种类还是次数,都render 2次。

异步中,无论多少种类还是次数,都render 2次。

15版本, class版本

this.setState是异步的,set 3次就会合并,在callback可以获取最新值

但是在setTimeout同步的。(set 3次就会执行三次)
15 class版本看这个地址

react18

js 复制代码
import React, { useState, useEffect } from 'react';
// 最新的react 16
function Test() {
    console.log('----render') // 默认执行2次
    const [countA, setCountA] = useState(111);
    const [countB, setCountB] = useState(222);
    function onClick() {
        // 一个种类,一个set执行2次render
        // 二个种类,各一次set,那么执行2次render
        // 二个种类及以上,执行2次render,还是执行2次
        setCountA(countA + 1)
        // setCountA(countA + 1)
        // setCountA(countA + 1)
        // setCountA(countA + 1)

        // setCountB(countB + 1)
        // setCountB(countB + 1)
        // setCountB(countB + 1)
        // setCountB(countB + 1)

        setTimeout(() => {
            // 一个种类,一个set执行2次render
            // 二个种类,各一次set,那么执行2次render
            // 二个种类及以上,执行2次render,还是执行2次
            // setCountA(countA + 1)
            // setCountA(countA + 1)
            // setCountA(countA + 1)
            // setCountA(countA + 1)

            // setCountB(countB + 1)
            // setCountB(countB + 1)
            // setCountB(countB + 1)
            // setCountB(countB + 1)
        });
    }
    useEffect(() => {
    }, []);

    return (
        <div>
            <p>{countA}-{countB}</p>
            <button onClick={onClick}>点击我</button>
        </div>
    )
}
export default Test;
react16
js 复制代码
import React, { useState, useEffect } from 'react';
// 最新的react 16
function Test() {
    console.log('--render') // 默认执行1次
    const [countA, setCountA] = useState(111);
    const [countB, setCountB] = useState(222);
    function onClick() {
        // 一个种类,一个set执行1次render
        // 二个种类,各一次set,那么执行1次render
        // 二个种类及以上,执行2次render,还是执行1次
        // setCountA(countA + 1)
        // setCountA(countA + 1)
        // setCountA(countA + 1)
        // setCountA(countA + 1)

        // setCountB(countB + 1)
        // setCountB(countB + 1)
        // setCountB(countB + 1)
        // setCountB(countB + 1)

        setTimeout(() => {
            // 一个种类,一个set执行1次render
            // 二个种类,各一次set,那么执行2次render
            // 二个种类及以上n,执行2次render及以上,n*2
            setCountA(countA + 1)
            setCountA(countA + 1)
            setCountA(countA + 1)
            setCountA(countA + 1)

            setCountB(countB + 1)
            setCountB(countB + 1)
            setCountB(countB + 1)
            setCountB(countB + 1)
        });
    }
    useEffect(() => {
    }, []);

    return (
        <div>
            <p>{countA}-{countB}</p>
            <button onClick={onClick}>点击我</button>
        </div>
    )
}
export default Test;
react16, 18
js 复制代码
import React, { useState } from 'react';

function App() {
    const [number, setNumber] = useState(0);
    function alertNumber() {
        setTimeout(() => {
            alert(number); // 操作步骤,先点击弹窗,然后快速+按钮,永远弹出的是0,16和18都这样子
        }, 3000);
    }
    return (
        <div className="App">
            <p>{number}</p>
            <button onClick={() => setNumber(number + 1)}>+</button>
            <button onClick={alertNumber}>alertNumber</button>
        </div>
    );
}
export default App;

一下的以前的博客,不可靠

react刷新几次问题

15版本, class版本

this.setState是异步的,set 3次就会合并,在callback可以获取最新值

但是在setTimeout同步的。(set 3次就会执行三次)
15 class版本看这个地址

16版本,hooks版本

setState set几次就会render几次,但是有惰性。不会批处理。

18版本

批处理了。异步。可以调用同步的api。

setTimeout中的也可以批处理了。

legacy模式下:命中batchedUpdates时是异步 未命中batchedUpdates时是同步的

concurrent模式下:都是异步的,react 17添加了这个concurrent模式

react 16 setTimeout异步中的setA不可控制

useState会对state进行逐个处理,useState的原理是用闭包机制,而setTimeout中任务是无法拿到闭包中的变量的,所以,当遇到 setTimeout时,在setTimeout拿不到最新的值。

setState会进行一个合对象的,则只会处理最后一次。

当遇到 setTimeout/setInterval/Promise.then(fn)/fetch 回调/xhr 网络回调时,react 都是无法控制的,这个根react本身的原因有关系。

react 18 中对setTimeout中连续两次的setA也进行了合并,不知道18中setTimeout可不可以控制。

clike 复制代码
const [a, setA] = useState(123);
console.log('----render');
return (
  <div className="App">
    <h1>{a}</h1>
    <button onClick={() => {
      // react 16 刷新两次, 结果仍然为124 react18刷新一次
      setA(a+1);
      setA(a+1);
    }}>fffff</button>
  </div>
);
----------------------------------------
const [number,setNumber] = useState(0);
function alertNumber(){
  setTimeout(()=>{
    alert(number); // 不论您点击多少次下边的click这里就是0
  },3000);
}
return (
    <>
        <p>{number}</p>
        <button onClick={()=>setNumber(number+1)}>+</button>
        <button onClick={alertNumber}>alertNumber</button>
    </>
)
----------------------------------------
export default function App() {
  console.log('render----');
  const [ca, setCa] = useState(1);
  const aclick = () => {
    setTimeout(() => {
      // 会执行两次,但是最后的结果只会+1
      setCa(ca + 1);
      setCa(ca + 1);
    });
  }
  return (
    <div className="App" onClick={aclick}>
      {ca}
    </div>
  );
}
相关推荐
子兮曰2 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰2 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万2 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝2 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋2 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁2 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
李少兄2 天前
JavaScript 隐式全局变量解析
javascript
汉堡大王95272 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大2 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师2 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端