React setState

相关代码题目setState


import React, {Suspense, lazy, useState, useEffect} from "react";
// JSX、VDOM、diff算法、Fiber架构、并发模式、合成事件
//  为什么React需要Fiber并发模式而Vue不需要 ???
// React18开发环境下,组件渲染时会被执行两次,是为了更早的验证组件完整的生命周期
// 生产环境下不会重复渲染
// ★ 不管是Vue还是React都是异步更新 异步渲染的,同步代码中无法获取到最新的值
// setValue(value + 1) 这种会合并更新
// setValue(value => value + 1) 这种不会合并更新
function Demo() {
    console.log('output-> Hello')
    const [value, setValue] = useState(100)
    function clickHandler() {
        setValue(value + 1)
        setValue(value + 1)
        console.log('output-> value1:: ', value)
        setValue((value) => value + 1)
        setValue((value) => value + 1)
        console.log('output-> value2:: ', value)
    }
    return (
        // React.Fragment 可以帮助你在不增加额外 DOM 节点的情况下返回多个元素
        <React.Fragment>
            <span>{value}</span>
            <button onClick={clickHandler}>increase</button>
        </React.Fragment>
    )
}
/**
 * 终端输出
 * app01
 * output-> Hello
 * app02
 * App.jsx:12 output-> value1::  100
 * App.jsx:15 output-> value2::  100
 * App.jsx:7 output-> Hello
 * 界面输出
 * 103
 * */
const App = () => {
    console.log('output-> app01', )
    useEffect(() => { // 组件首次渲染完成后才会执行
        console.log('output-> app02')
    })
    return (
        <div>
            <Demo/>
        </div>
    );
};

export default App;

setState是同步还是异步 指的是状态更新是同步还是异步的,setState调用都是异步的

为什么setState设计是异步的?

  • 提高应用性能,每一次setState都会触发组件重渲染包括协调、调度、渲染层的过程

setState会触发什么

  1. react-scheduler会接收到一个更新请求,将该更新包装成一个任务task对象将更新逻辑存放在Task对象的callback中并放到任务队列等待调度
  2. react-reconciler会协调react-scheduler的执行提供Fiber树的构造逻辑、调和算法并根据状态更新创建新的Fiber树
  3. react-reconciler中调和算法会对Fiber树进行比较获取差异结果并通过react-dom进行增量更新

setState(updater, [callback])

  1. setState被视为请求更新而不是立即更新
  2. updater的返回值会和state进行浅合并(会保留未更新的部分)
  3. 第二个可选的回调函数会在合并完成之后执行
  4. this.setState在shouldComponentUpdate()返回true后,render()方法之前才会更新

setState的第二个参数 callback

callback会在状态更新并且组件重新渲染之后执行

React18之后所有setState都是异步的若需要实现通过需要使用 flushSync实现

flushSync(() => {
        this.setState({data: 2});
      });
      console.log('data', this.state.data);
      flushSync(() => {
        this.setState({data: 3});
      });
      console.log('data', this.state.data);
posted @ 2025-03-01 23:05  Felix_Openmind  阅读(16)  评论(0)    收藏  举报
*{cursor: url(https://files-cdn.cnblogs.com/files/morango/fish-cursor.ico),auto;}