React面试葵花宝典之二

36.Fiber的更新机制

React Fiber 更新机制详解

React Fiber 是 React 16 引入的核心架构重构,旨在解决可中断渲染优先级调度 问题,提升复杂应用的流畅性。其核心思想是将渲染过程拆分为可控制的工作单元,实现更细粒度的任务管理。以下是其核心机制:


一、Fiber 架构的设计目标
  1. 可中断与恢复:允许渲染过程被高优先级任务(如用户输入)打断,后续恢复。
  2. 增量渲染:将渲染任务拆分为多个小任务(时间分片),避免阻塞主线程。
  3. 优先级调度:根据任务类型(如动画、数据加载)分配不同优先级。
  4. 并发模式支持:为 Suspense、Transition 等特性提供底层支持。

二、Fiber 节点:工作单元的基础

每个 Fiber 节点对应一个组件或 DOM 节点,构成链表树结构,包含以下关键信息:

  • 组件类型:函数/类组件、HTML 标签等。

  • 状态与 Propsstatepropscontext

  • 副作用标记 :增/删/更新 DOM、调用生命周期等(通过 flags 字段标识)。

  • 链表指针

    • child:指向第一个子节点。
    • sibling:指向下一个兄弟节点。
    • return:指向父节点。
  • 优先级lane 模型标记任务优先级(如 SyncLane、InputContinuousLane)。


三、更新流程:从触发到提交
1. 触发更新
  • 来源setStateuseState、父组件重渲染、Context 变更等。
  • 创建更新对象:包含新状态、优先级等信息,添加到 Fiber 的更新队列。
2. 调度阶段(Scheduler)
  • 任务分片:将整个渲染流程拆分为多个 Fiber 节点的处理单元。
  • 优先级排序 :使用 lane 模型分配优先级,高优先级任务可抢占低优先级。
  • 时间切片 :通过 requestIdleCallbackMessageChannel 在浏览器空闲时段执行任务。
3. 协调阶段(Reconciler)
  • 构建 WorkInProgress 树:在内存中生成新 Fiber 树(双缓存机制)。
  • Diff 算法 :对比新旧 Fiber 节点,标记变更(如 PlacementUpdateDeletion)。
  • 生命周期触发 :执行函数组件的渲染、类组件的 render 方法。
4. 提交阶段(Commit)
  • 同步执行:不可中断,一次性将变更应用到 DOM。

  • 副作用处理

    • DOM 操作:增删改节点。
    • 生命周期 :类组件的 componentDidMount/Update
    • HooksuseLayoutEffect 回调。
  • 切换当前树 :将 WorkInProgress 树标记为 current 树。


四、优先级调度与中断机制
  • Lane 模型 :用二进制位表示优先级(如 0b00010b0010 可合并为 0b0011)。
  • 高优先级抢占:用户交互触发的更新(如按钮点击)可中断正在进行的低优先级渲染(如大数据列表渲染)。
  • 饥饿问题处理:长时间未执行的低优先级任务会被提升优先级。

示例场景

用户输入搜索关键词时,输入框的即时响应(高优先级)会中断后台数据渲染(低优先级)。


五、双缓存技术
  • Current 树:当前屏幕上显示的 Fiber 树。
  • WorkInProgress 树:正在构建的新树,完成后替换 Current 树。
  • 优势:减少渲染过程中的页面闪烁,确保原子性更新。

六、并发模式下的更新
  • 过渡更新(Transition) :通过 startTransition 标记非紧急更新(如页面切换),可被用户交互打断。

    const [isPending, startTransition] = useTransition();
    startTransition(() => {
      setPage(newPage); // 低优先级更新
    });
    
  • Suspense:配合懒加载组件,在数据加载时显示 fallback UI。


七、性能优化启示
  1. 减少渲染粒度 :使用 React.memouseMemo 避免无效渲染。
  2. 合理分配优先级 :紧急操作使用高优先级,长任务用 startTransition 包裹。
  3. 优化 Fiber 树深度:扁平化组件结构,减少协调时间。

总结

React Fiber 通过可中断的异步渲染优先级调度,彻底改变了 React 的渲染机制。其核心价值在于:

  • 更流畅的交互:高优先级任务快速响应,避免界面卡顿。
  • 更高效的渲染:增量更新减少主线程阻塞。
  • 面向未来的扩展:为并发特性(如 Suspense、Server Components)奠定基础。

37.React18有哪些更新

React 18 主要更新详解

React 18 引入了多项重要改进和新特性,旨在提升性能、开发体验及扩展能力。以下是其核心更新内容:


1. 并发渲染(Concurrent Rendering)
  • 核心机制:通过可中断的渲染过程,实现任务优先级调度与时间分片。

    • 并发模式(Concurrent Mode) :现称为"并发特性",无需全局开启,按需使用。
    • API支持startTransitionuseDeferredValue 等。
  • 优势

    • 高优先级任务(如用户输入)可中断低优先级渲染,提升交互流畅度。
    • 支持复杂场景下的无缝过渡(如页面切换、数据加载)。

示例

import { startTransition } from 'react';

// 标记非紧急更新
startTransition(() => {
  setSearchQuery(input); // 延迟渲染搜索结果,保持输入响应
});

2. 自动批处理(Automatic Batching)
  • 改进点:在更多场景下合并状态更新,减少渲染次数。

    • React 17及之前:仅在事件处理函数中批处理。
    • React 18:扩展至Promise、setTimeout等异步操作。
  • 效果:降低不必要的重渲染,优化性能。

示例

// React 18:两次setState合并为一次渲染
setTimeout(() => {
  setCount(1);
  setFlag(true);
}, 1000);

3. 新的根API(createRoot)
  • 替换旧API :使用 createRoot 替代 ReactDOM.render,启用并发特性。

  • 用法

    import { createRoot } from 'react-dom/client';
    
    const root = createRoot(document.getElementById('root'));
    root.render(<App />);
    

4. Suspense 增强
  • 服务端渲染(SSR)支持

    • 流式HTML传输:逐步发送HTML,加速首屏加载。
    • 选择性Hydration:优先为交互部分注水,提升可交互时间(TTI)。
  • 客户端扩展:支持在更多场景包裹异步组件或数据加载。

示例

<Suspense fallback={<Loading />}>
  <AsyncComponent />
</Suspense>

5. 新Hooks API
  • useId:生成唯一ID,解决SSR与客户端ID不一致问题。

    const id = useId(); // 生成如 ":r1:"
    
  • useSyncExternalStore:简化外部状态库(如Redux)集成。

    const state = useSyncExternalStore(store.subscribe, store.getState);
    
  • useInsertionEffect:适用于CSS-in-JS库动态插入样式。

    useInsertionEffect(() => {
      const style = document.createElement('style');
      style.innerHTML = `.css { color: red }`;
      document.head.appendChild(style);
    });
    

6. 过渡API(Transitions)
  • 区分紧急/非紧急更新 :通过 startTransition 延迟非关键渲染。

  • UI反馈useTransition 提供 isPending 状态,显示加载指示。

    const [isPending, startTransition] = useTransition();
    
    startTransition(() => {
      setTab(newTab); // 非紧急导航
    });
    
    return isPending ? <Spinner /> : <Content />;
    

7. 严格模式增强
  • 开发环境行为

    • 双调用Effects:模拟组件卸载/挂载,暴露副作用问题。
    • 组件重复挂载:检查是否正确处理清理逻辑(如定时器、订阅)。

8. 服务端组件(实验性)
  • 核心能力

    • 服务端渲染组件:在服务端执行,减少客户端代码体积。
    • 无缝数据获取:直接访问后端API,传递序列化数据至客户端。
  • 使用场景:静态内容、SEO优化、性能敏感页面。

示例

// ServerComponent.server.js
export default function ServerComponent() {
  const data = fetchData(); // 服务端执行
  return <div>{data}</div>;
}

9. 其他改进
  • 性能优化:减少内存占用,提升大型应用渲染效率。
  • TypeScript支持:更严格的类型推断,减少显式类型声明。
  • 开发者工具:增强并发模式调试支持,可视化渲染优先级。

升级指南

  1. 兼容性:React 18 保持向后兼容,逐步采用新特性。

  2. 迁移步骤

    • 使用 createRoot 替换 ReactDOM.render
    • 按需引入并发API(如 startTransition)。
    • 测试严格模式下的副作用处理。

总结

React 18 通过并发渲染、自动批处理、Suspense增强等特性,显著提升了应用性能与用户体验。开发者可通过渐进式升级,利用新API优化交互流畅度与渲染效率,同时为未来特性(如服务端组件)奠定基础。

38.Rect19有哪些新特性

具体详见官网:

中文:React 19 新特性

英文:React 19 新特性

核心新特性

1. Actions

解决问题:简化数据变更和状态更新流程

  • 以前需要手动处理待定状态、错误、乐观更新和顺序请求
  • 需要维护多个状态变量(isPending, error 等)

新特性

typescript 复制代码
function UpdateName() {
  const [state, submitAction, isPending] = useActionState(
    async (prevState, formData) => {
      const error = await updateName(formData.get("name"));
      if (error) return error;
      redirect("/path");
      return null;
    },
    null
  );

  return (
    <form action={submitAction}>
      <input name="name" />
      <button disabled={isPending}>Update</button>
      {state?.error && <p>{state.error}</p>}
    </form>
  );
}

主要改进

  • 自动处理待定状态
  • 内置错误处理
  • 支持乐观更新
  • 简化表单处理

2. useFormStatus

解决问题:简化表单组件状态访问

  • 避免通过 props 传递表单状态
  • 提供统一的表单状态访问方式
typescript 复制代码
function SubmitButton() {
  const { pending, data, method } = useFormStatus();
  return (
    <button disabled={pending}>
      {pending ? 'Submitting...' : 'Submit'}
    </button>
  );
}

3. useOptimistic

解决问题:提供更好的用户体验

  • 立即显示操作结果
  • 处理异步操作的状态更新
typescript 复制代码
function LikeButton({ id }) {
  const [likes, setLikes] = useState(0);
  const [optimisticLikes, addOptimisticLike] = useOptimistic(
    likes,
    (state, increment) => state + increment
  );

  async function handleLike() {
    addOptimisticLike(1); // 立即更新 UI
    await updateLikes(id); // 后台进行实际更新
  }
}

4. use() Hook

解决问题:统一资源使用方式

  • 简化 Promise 和 Context 的使用
  • 支持条件性使用
  • 提供更好的类型推断
typescript 复制代码
function Comments({ commentsPromise }) {
  const comments = use(commentsPromise); // 自动处理 Suspense
  return comments.map(comment => <p>{comment}</p>);
}

架构改进

1. Document 流式渲染

解决问题:改善首次加载体验

  • 支持 HTML 流式传输
  • 优化资源加载顺序
typescript 复制代码
function AsyncPage() {
  return (
    <Document>
      <Suspense fallback={<Loading />}>
        <AsyncContent />
      </Suspense>
    </Document>
  );
}

2. 资源处理优化

样式表支持

解决问题:简化样式管理

  • 自动处理样式表加载顺序
  • 支持组件级样式声明
typescript 复制代码
function Component() {
  return (
    <>
      <link rel="stylesheet" href="styles.css" precedence="default" />
      <div className="styled-content">...</div>
    </>
  );
}
异步脚本支持

解决问题:优化脚本加载

  • 自动处理脚本去重
  • 优化加载优先级
typescript 复制代码
function MyComponent() {
  return (
    <div>
      <script async={true} src="widget.js" />
      <div>Widget Content</div>
    </div>
  );
}

开发体验改进

1. 错误处理增强

解决问题:提供更清晰的错误信息

  • 消除重复错误日志
  • 提供更详细的错误上下文
typescript 复制代码
createRoot(container, {
  onCaughtError: (error) => {
    // 错误边界捕获的错误
  },
  onUncaughtError: (error) => {
    // 未被捕获的错误
  },
  onRecoverableError: (error) => {
    // 可恢复的错误
  }
});

2. 自定义元素支持

解决问题:改善与 Web Components 的集成

  • 完整支持自定义元素
  • 正确处理属性和属性传递

最佳实践建议

  1. 渐进式采用

    • 优先使用新的表单处理方式
    • 在关键交互中使用乐观更新
    • 利用新的资源加载优化
  2. 性能优化

    • 使用流式渲染改善加载体验
    • 合理使用资源预加载
    • 优化并发更新
  3. 错误处理

    • 使用新的错误边界
    • 实现适当的降级策略
    • 监控错误模式

服务器组件

1. 服务器组件基础

解决问题:优化应用性能和开发体验

  • 减少客户端 bundle 大小
  • 直接访问后端资源
  • 改善数据获取模式
typescript 复制代码
// 服务器组件
async function Notes() {
  // 直接访问数据库,无需 API 层
  const notes = await db.notes.getAll();
  
  return (
    <div>
      {notes.map(note => (
        <Expandable key={note.id}>
          <p>{note.content}</p>
        </Expandable>
      ))}
    </div>
  );
}

2. 服务器组件与客户端组件集成

解决问题:平滑处理服务器和客户端组件交互

  • 支持渐进式增强
  • 保持交互性
  • 优化数据流
typescript 复制代码
// 服务器组件
import Expandable from './Expandable';  // 客户端组件

async function NotesContainer() {
  const notes = await db.notes.getAll();
  
  return (
    <div>
      {/* 服务器组件可以渲染客户端组件 */}
      <Expandable>
        <NotesList notes={notes} />
      </Expandable>
    </div>
  );
}

// 客户端组件
'use client'
function Expandable({ children }) {
  const [expanded, setExpanded] = useState(false);
  
  return (
    <div>
      <button onClick={() => setExpanded(!expanded)}>
        {expanded ? 'Collapse' : 'Expand'}
      </button>
      {expanded && children}
    </div>
  );
}

3. 异步组件

解决问题:简化异步数据处理

  • 支持 async/await 语法
  • 自动处理 Suspense 集成
  • 优化加载状态
typescript 复制代码
// 服务器组件中的异步数据获取
async function Page({ id }) {
  const note = await db.notes.get(id);
  // 开始获取评论但不等待
  const commentsPromise = db.comments.get(id);
  
  return (
    <div>
      <h1>{note.title}</h1>
      <Suspense fallback={<Loading />}>
        <Comments commentsPromise={commentsPromise} />
      </Suspense>
    </div>
  );
}

Refs 作为 Props

1. 将 ref 作为 prop

从 React 19 开始,你现在可以在函数组件中将 ref 作为 prop 进行访问:

typescript 复制代码
function MyInput({placeholder, ref}) {
  return <input placeholder={placeholder} ref={ref} />
}

//...
<MyInput ref={ref} />

新的函数组件将不再需要 forwardRef,我们将发布一个 codemod 来自动更新你的组件以使用新的 ref prop。在未来的版本中,我们将弃用并移除 forwardRef。

2. Ref 稳定性改进

解决问题:优化 ref 更新和同步

  • 更可预测的 ref 更新时机
  • 更好的并发模式支持
  • 改进的性能特性
typescript 复制代码
function AutoFocusInput() {
  const inputRef = useRef<HTMLInputElement>(null);
  
  // ref 回调模式的改进
  const setRef = useCallback((element: HTMLInputElement | null) => {
    if (element) {
      element.focus();
    }
  }, []);
  
  return <input ref={setRef} />;
}

服务器组件最佳实践

  1. 数据获取策略

    • 在服务器组件中直接访问数据源
    • 使用流式传输处理大量数据
    • 实现适当的缓存策略
  2. 组件分割

    • 将有状态逻辑的组件标记为客户端组件
    • 保持服务器组件纯粹
    • 优化组件边界
  3. 性能优化

    • 使用服务器组件减少客户端 bundle
    • 实现渐进式加载
    • 优化数据预取
typescript 复制代码
// 示例:优化的服务器组件结构
async function BlogPost({ id }) {
  const post = await db.posts.get(id);
  const authorPromise = db.authors.get(post.authorId);
  const commentsPromise = db.comments.get(id);
  
  return (
    <article>
      <h1>{post.title}</h1>
      <Suspense fallback={<AuthorSkeleton />}>
        <Author authorPromise={authorPromise} />
      </Suspense>
      <Content>{post.content}</Content>
      <Suspense fallback={<CommentsSkeleton />}>
        <Comments commentsPromise={commentsPromise} />
      </Suspense>
    </article>
  );
}

注意事项

  1. 服务器组件限制

    • 不能使用浏览器 API
    • 不能使用状态和生命周期
    • 需要正确处理数据获取错误
  2. Ref 使用考虑

    • 注意 ref 的生命周期
    • 合理处理 ref 清理
    • 避免过度依赖 ref
  3. 性能注意事项

    • 平衡服务器和客户端渲染
    • 合理使用 Suspense 边界
    • 优化数据预加载策略
      详细请看链接

39.React为什么不直接使用this.state改变数据

在 React 中,不能直接通过 this.state 来改变数据 ,而必须使用 this.setState() 来更新状态。这背后有几个关键的原因,主要是为了保证 组件的可预测性、性能优化避免直接修改状态 所带来的潜在问题。接下来,我将详细解释这些原因。

1. 不可变数据和状态管理原则

React 提倡 不可变数据 (immutable data)原则,即状态对象一旦创建,它的值就不应该直接修改。直接修改 this.state 会导致组件行为变得难以预测,难以追踪和调试。通过 this.setState(),React 可以保证每次状态更新时,状态对象都是全新的对象,而不是直接修改原有对象。

为什么要避免直接修改 this.state

  • 直接修改状态会破坏数据的不可变性,使得 React 无法检测到变化。
  • 状态不再是新的引用,这使得 React 无法有效地进行比较,进而影响渲染效率。

举个例子,如果直接修改 this.state

this.state.someValue = newValue;  // 不推荐

这样 React 就不会知道状态发生了变化,因此不会触发重新渲染,也就无法同步 UI 和状态。

而通过 this.setState()

this.setState({ someValue: newValue });  // 推荐

this.setState() 会创建一个新的状态对象,确保 React 能检测到状态变化,并触发 UI 更新。


2. 异步更新与批量更新

this.setState() 的更新是异步的,而直接修改 this.state 是同步的。React 内部有一种机制,用来批量更新状态,以减少不必要的重新渲染。这种机制不仅提高了性能,还避免了多次渲染的重复计算。

例如,假设你直接修改了 this.state,并且立即访问了 this.state 来获取新值。由于 React 的 setState() 是异步的,直接修改 this.state 可能会导致你获取到的状态值不是更新后的值。

this.setState({ count: this.state.count + 1 });
console.log(this.state.count); // 可能不会立即反映出最新的状态

React 会将多个 setState() 调用合并到一个批量更新中,以减少不必要的渲染和性能开销。通过使用 this.setState(),React 可以处理这些合并和异步更新的操作。


3. 性能优化

this.setState() 触发的更新过程与直接修改 this.state 的过程有所不同。当调用 setState() 时,React 会合并当前的状态和新的状态,只有发生了变化的部分会被更新。这对于性能优化至关重要。

如果你直接修改 this.state,React 就无法知道哪些部分发生了变化,也就无法进行智能的 diff 和批量更新。例如:

this.state.count = 10;  // 直接修改
this.setState({ count: 10 });  // 通过 setState 更新

setState() 中,React 会比较前后的状态,判断是否需要重新渲染组件,而直接修改 this.state 则无法触发这种比较。


4. 组件的生命周期和渲染

this.setState() 触发状态更新时,React 会在合适的生命周期方法中触发组件的重新渲染。例如,在状态更新时,shouldComponentUpdatecomponentDidUpdate 等生命周期方法会被调用,以便开发者可以在状态变化时执行一些操作。如果直接修改 this.state,React 不会知道组件状态发生变化,进而不会触发这些生命周期方法。

这会导致一些问题,比如无法对比新旧状态、无法做条件渲染等操作。


5. React 状态更新的队列机制

React 通过维护一个更新队列来优化状态的更新和渲染。当你调用 this.setState() 时,React 会把状态更新请求放入一个队列,批量处理这些更新。在队列中的多个状态更新可以合并,这避免了不必要的重新渲染,提高了性能。

直接修改 this.state 不会加入更新队列,React 不会触发它的重新渲染机制,因此无法享受 React 的批量更新和性能优化。


6. 追踪组件的变化

React 使用 this.setState() 来管理组件状态,并且通过对比旧的虚拟 DOM 和新的虚拟 DOM,来决定哪些部分需要重新渲染。这个过程需要 React 在底层追踪和比较状态,而直接修改 this.state 会使得这个追踪变得困难,影响性能优化。

通过 this.setState(),React 能够确保组件状态的变化得到跟踪,并且在状态变化时触发重新渲染,确保 UI 始终与状态一致。


7. React 16+ 的 Fiber 架构

在 React 16 及更高版本中,React 引入了 Fiber 架构 ,这使得 React 的渲染变得更加灵活和高效。通过 this.setState(),React 能够控制每一次渲染的优先级,并且通过增量更新来保持 UI 响应性。如果你直接修改 this.state,这种增量更新机制就无法发挥作用。


总结:

  • 数据不可变性this.setState() 遵循不可变数据的原则,避免直接修改原有状态。
  • 异步和批量更新this.setState() 支持异步更新,React 可以批量处理多个状态更新,提升性能。
  • 生命周期管理 :通过 setState,React 能够触发生命周期钩子,确保组件正确更新。
  • 性能优化this.setState() 可以通过智能的差异化更新减少不必要的 DOM 操作,而直接修改 this.state 会跳过这一过程。

因此,直接修改 this.state 会破坏 React 的更新机制,导致状态和 UI 不一致,影响性能和可维护性。React 的设计理念和架构要求我们通过 this.setState() 来更新状态,从而确保更高效和可预测的渲染过程。

40.原来的react虚拟dom树遍历是深度优先遍历还是层序遍历?存储是链表存储还是栈存储,fiber机制下的是如何存储

React 虚拟DOM遍历与存储机制详解


一、传统虚拟DOM(React 15及之前)
  1. 遍历方式深度优先遍历(DFS)

    • 递归处理:从根组件开始,递归处理每个组件及其子组件,直到叶子节点,再回溯处理兄弟节点。

    • 顺序示例

      A → A.child B → B.child C → C.child D → 回溯到 B → B.sibling E → E.child F
      
  2. 存储结构隐式调用栈

    • 依赖调用栈:递归调用栈隐式管理遍历过程,无显式数据结构存储节点关系。

    • 缺点

      • 不可中断:递归一旦开始必须执行完毕,导致主线程阻塞。
      • 性能瓶颈:深层嵌套组件树易引发栈溢出或卡顿。

二、Fiber架构(React 16+)
  1. 遍历方式可中断的迭代式深度优先遍历

    • 顺序不变:仍按深度优先顺序处理节点(与之前一致)。

    • 实现变化 :从递归改为循环+链表指针手动遍历,支持暂停与恢复。

    • 流程示例

      let fiber = rootFiber;
      while (fiber) {
        process(fiber);      // 处理当前节点
        if (fiber.child) {
          fiber = fiber.child; // 优先处理子节点
          continue;
        }
        while (fiber) {
          completeWork(fiber); // 完成当前节点
          if (fiber.sibling) {
            fiber = fiber.sibling; // 转向兄弟节点
            break;
          }
          fiber = fiber.return;    // 回溯父节点
        }
      }
      
  2. 存储结构显式链表树

    • Fiber节点结构

      interface Fiber {
        tag: ComponentType;      // 组件类型
        child: Fiber | null;     // 第一个子节点
        sibling: Fiber | null;   // 下一个兄弟节点
        return: Fiber | null;    // 父节点
        alternate: Fiber | null; // 指向另一棵树(双缓存)
        flags: number;           // 副作用标记(增/删/更新)
        lanes: Lanes;            // 优先级
        // ...其他字段(stateNode、props等)
      }
      
    • 双缓存机制

      • Current树:当前渲染的树(对应屏幕显示内容)。
      • WorkInProgress树:正在构建的新树,完成后替换Current树。
      • 优势:避免渲染中间状态导致的UI闪烁。

三、Fiber架构的核心改进
维度 传统虚拟DOM Fiber架构
遍历控制 递归(不可中断) 迭代(可中断 + 恢复)
数据结构 隐式调用栈 显式链表(child/sibling/return)
任务调度 同步执行 优先级调度 + 时间分片
性能优化 易阻塞主线程 增量渲染,避免卡顿
扩展能力 有限 支持并发模式(Suspense/Transition)

四、Fiber遍历流程示例

假设组件树结构为:

A
├─ B
│  ├─ C
│  └─ D
└─ E
   └─ F

遍历顺序

  1. 进入A → 处理A
  2. 进入A.child B → 处理B
  3. 进入B.child C → 处理C
  4. C无子节点 → 完成C,回溯到B
  5. 进入B.sibling D → 处理D
  6. D无子节点 → 完成D,回溯到B → 完成B,回溯到A
  7. 进入A.sibling E → 处理E
  8. 进入E.child F → 处理F
  9. F无子节点 → 完成F,回溯到E → 完成E,回溯到A → 完成A

五、Fiber架构的优势
  1. 可中断渲染:高优先级任务(如用户输入)可打断低优先级渲染。
  2. 增量更新:将渲染任务拆分为多个帧执行,避免主线程阻塞。
  3. 精准副作用提交 :通过 flags 标记变更,一次性提交DOM操作。
  4. 并发模式支持:实现服务端渲染流式输出、Suspense等高级特性。

总结

  • 传统虚拟DOM:深度优先遍历 + 递归调用栈,简单但不可中断。
  • Fiber架构:深度优先遍历 + 显式链表结构,通过迭代实现可中断渲染,结合优先级调度与双缓存机制,为React带来革命性性能提升与扩展能力。
  • 核心价值:将同步渲染转化为异步可调度任务,使复杂应用保持流畅交互。

41.React如何创建工程环境(js,ts),eject的作用是什么?

42.React常见hooks有哪些

相关推荐
mqwguardain5 分钟前
DOM 事件 & HTML 标签属性速查手册
前端·javascript·python·html
李奶酪16 分钟前
WebSocket相关技术
前端
m0_7482417021 分钟前
rust web框架actix和axum比较
前端·人工智能·rust
AC-PEACE1 小时前
React 项目创建与文件基础结构关系
前端·javascript·react.js
IT、木易1 小时前
白话React第九章React 前沿技术与企业级应用实战
前端·react.js·前端框架
xuxiaoxie1 小时前
安装electron 提示RequestError: certificate has expired
前端·javascript·electron
Czi橙1 小时前
MySQL当中的Lock
java·数据库·mysql·面试
GISer_Jing2 小时前
React底层常见的设计模式
javascript·react.js·设计模式
做怪小疯子2 小时前
三个小时学完vue3(一)
前端·javascript·vue.js
LXY202305042 小时前
利用props实现子传父组件
java·服务器·前端