刷刷题48 (setState常规问答)

‌1. 为什么说setState是异步的?React如何处理多个setState调用? ‌

  • ‌异步原因 ‌:为了优化性能,React会将多个setState合并为一次更新,减少不必要的渲染次数(批处理机制)。

  • ‌处理方式‌:

    kotlin 复制代码
    // 连续调用会被合并,最终count只+1
    this.setState({ count: this.state.count + 1 });
    this.setState({ count: this.state.count + 1 });

    React内部通过updater队列收集多个更新,在事件循环末尾统一处理。


‌2. 如何强制在setState后立即获取最新状态? ‌

使用setState的‌回调函数 ‌或‌Promise封装‌:

javascript 复制代码
// 方式1:回调函数
this.setState({ count: 1 }, () => console.log(this.state.count));

// 方式2:async/await(需自行封装)
const setStateAsync = (state) => new Promise(resolve => this.setState(state, resolve));
await setStateAsync({ count: 1 });

‌3. 哪些场景下setState会同步执行? ‌

在React的‌控制范围之外‌的代码中会同步更新:

  • setTimeout/setInterval
  • 原生DOM事件监听器
  • Promise回调
javascript 复制代码
setTimeout(() => {
  this.setState({ count: 1 }); // 同步更新
  console.log(this.state.count); // 输出1
}, 0);

‌4. setState(partialState, callback)和this.state = ...直接修改的区别? ‌

  • ‌**setState**‌:

    • 触发组件重新渲染
    • 遵守React的更新队列机制
    • 支持批处理优化
  • ‌**直接修改this.state**‌:

    • 不会触发渲染(状态不更新到UI)
    • 破坏React状态管理机制,导致数据不一致

‌5. 为什么说在setState中依赖this.state的值是危险的?如何解决? ‌

  • ‌危险原因‌:异步更新可能导致获取的是过期状态

    kotlin 复制代码
    // ❌ 错误:可能基于旧值计算
    this.setState({ count: this.state.count + 1 });
  • ‌解决方案 ‌:使用‌函数式更新‌

    javascript 复制代码
    // ✅ 正确:接收前一个状态
    this.setState((prevState) => ({ count: prevState.count + 1 }));

‌6. React 18中setState的批处理机制有哪些改进? ‌

  • ‌React 17及之前‌:仅在React事件处理函数中自动批处理

  • ‌React 18+ ‌:

    • 所有场景(包括Promise、setTimeout等)默认自动批处理
    • 可使用flushSync强制同步更新:
    javascript 复制代码
    import { flushSync } from 'react-dom';
    flushSync(() => this.setState({ count: 1 })); // 立即更新

‌7. 如何避免setState导致的不必要重复渲染? ‌

  • ‌浅比较优化‌:

    scala 复制代码
    class Component extends React.PureComponent { // 自动浅比较props/state
      state = { list: [] };
      addItem = () => {
        // ✅ 正确:返回新数组
        this.setState(prev => ({ list: [...prev.list, newItem] }));
      }
    }
  • ‌手动控制‌:

    javascript 复制代码
    shouldComponentUpdate(nextProps, nextState) {
      return nextState.count !== this.state.count; // 仅当count变化时更新
    }

‌8. 在componentWillUpdate中调用setState会发生什么? ‌

  • ‌引发无限循环 ‌:
    componentWillUpdate → setState → 重新渲染 → 再次触发componentWillUpdate
  • ‌解决方案 ‌:
    禁止在此生命周期中调用setState,改用componentDidUpdate处理副作用。

‌9. 为什么推荐在setState中返回不可变数据?如何正确实现? ‌

  • ‌不可变性优势‌:

    • 便于React快速比较状态变化
    • 避免引用类型数据共享导致的副作用
  • ‌正确写法‌:

    kotlin 复制代码
    // ✅ 对象
    this.setState({ user: { ...this.state.user, name: 'Alice' } });
    
    // ✅ 数组
    this.setState({ list: [...this.state.list, newItem] });

‌10. setState在异步操作(如AJAX请求)中可能遇到什么问题?如何解决? ‌

  • ‌竞态条件(Race Condition) ‌:

    当多个异步操作返回顺序不确定时,可能导致状态覆盖

  • ‌解决方案‌:

    1. 使用AbortController取消过期请求
    2. 函数式更新确保基于最新状态:
    ini 复制代码
    fetchData().then(data => {
      this.setState(prev => ({ 
        list: prev.filterId === currentId ? data : prev.list 
      }));
    });
相关推荐
Csvn1 小时前
并发模式:让渲染学会排队、插队和让路
前端
可乐鸡翅yeah_1 小时前
新手梳理:M3U8 线上问题,哪些是前端锅,哪些是后端锅
前端·ios·音视频·实时音视频·m3u8·音视频在线播放
Flynt1 小时前
Linear 用 1000 个 PR 换掉 styled-components,我写了 200 个按钮,把这笔账复现了一遍
前端·css·preact
JavaGuide2 小时前
NVIDIA 又开源了!这次给 AI Agent 加上权限管控
前端·后端
excel3 小时前
prisma 如何处理数据库竞态
前端·数据库·后端
莪_幻尘4 小时前
Skill 体检:30 个 Skill 全凭感觉?体检器先自曝了 8 个“假 0 分
前端·人工智能·llm
风骏时光牛马4 小时前
AI模型综合能力评测:性能、指令遵循与多场景实测对比
前端
Frag0ut4 小时前
Chrome与Chromium内核浏览器在Windows 11上的新特性全景解析
前端·chrome·windows·web安全·chromium·gemini ai·playready drm
此时不提桶,更待何时4 小时前
05-03-B-ClickHouse与OLAP面试与生产事故实战
clickhouse·面试·nosql
hiahiahia1235 小时前
实现完整 Tool Dispatcher
开发语言·前端