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>
  );
}
相关推荐
bin91531 小时前
DeepSeek 助力 Vue 开发:打造丝滑的复制到剪贴板(Copy to Clipboard)
前端·javascript·vue.js·ecmascript·deepseek
晴空万里藏片云3 小时前
elment Table多级表头固定列后,合计行错位显示问题解决
前端·javascript·vue.js
曦月合一3 小时前
html中iframe标签 隐藏滚动条
前端·html·iframe
奶球不是球3 小时前
el-button按钮的loading状态设置
前端·javascript
kidding7233 小时前
前端VUE3的面试题
前端·typescript·compositionapi·fragment·teleport·suspense
无责任此方_修行中5 小时前
每周见闻分享:杂谈AI取代程序员
javascript·资讯
Σίσυφος19005 小时前
halcon 条形码、二维码识别、opencv识别
前端·数据库
学代码的小前端5 小时前
0基础学前端-----CSS DAY13
前端·css
dorabighead6 小时前
JavaScript 高级程序设计 读书笔记(第三章)
开发语言·javascript·ecmascript
css趣多多6 小时前
案例自定义tabBar
前端