MST

星途 面试题库

面试题:React批量更新机制与异步操作的交互

考虑如下场景,在React组件中,有一个异步函数 `fetchData`,在这个函数内部会触发多个状态更新:<pre>async function fetchData() { const response = await fetch('/api/data'); const data = await response.json(); setData1(data.part1); setData2(data.part2); }</pre> 这里的状态更新是否会被React的批量事件更新机制处理?如果不会,如何手动实现类似的批量更新效果?
43.7万 热度难度
前端开发React

知识考点

AI 面试

面试题答案

一键面试
  1. 状态更新是否会被React的批量事件更新机制处理
    • 在React中,批量更新机制主要针对React合成事件(如 onClick 等)和生命周期函数内的状态更新。而在上述 fetchData 这样的异步函数中,状态更新不会被React的批量事件更新机制自动处理。这是因为异步操作(如 async/await)处于React合成事件和生命周期函数的“外部”,React无法感知到这些异步操作中的状态更新,所以会导致多次独立的渲染。
  2. 如何手动实现类似的批量更新效果
    • 在React中,可以使用 unstable_batchedUpdates 函数(在React 18之前)或 flushSync 函数(从React 18开始推荐)来手动实现批量更新效果。
    • React 18之前(使用 unstable_batchedUpdates
      import React, { useState } from'react';
      import { unstable_batchedUpdates } from'react-dom';
      
      const MyComponent = () => {
        const [data1, setData1] = useState(null);
        const [data2, setData2] = useState(null);
      
        async function fetchData() {
          const response = await fetch('/api/data');
          const data = await response.json();
          unstable_batchedUpdates(() => {
            setData1(data.part1);
            setData2(data.part2);
          });
        }
      
        return (
          <div>
            <button onClick={fetchData}>Fetch Data</button>
            <p>Data1: {data1}</p>
            <p>Data2: {data2}</p>
          </div>
        );
      };
      
      export default MyComponent;
      
    • React 18及之后(使用 flushSync
      import React, { useState } from'react';
      import { flushSync } from'react-dom';
      
      const MyComponent = () => {
        const [data1, setData1] = useState(null);
        const [data2, setData2] = useState(null);
      
        async function fetchData() {
          const response = await fetch('/api/data');
          const data = await response.json();
          flushSync(() => {
            setData1(data.part1);
            setData2(data.part2);
          });
        }
      
        return (
          <div>
            <button onClick={fetchData}>Fetch Data</button>
            <p>Data1: {data1}</p>
            <p>Data2: {data2}</p>
          </div>
        );
      };
      
      export default MyComponent;
      
    • flushSync 会强制React在调用结束时立即同步更新状态,并且会合并多个状态更新,从而避免不必要的多次渲染,达到类似批量更新的效果。unstable_batchedUpdates 也有类似功能,但在React 18后推荐使用 flushSync