导航


HTML

CSS

JavaScript

浏览器 & 网络

版本管理

框架

构建工具

TypeScript

性能优化

软实力

算法

UI、组件库

Node

业务技能

针对性攻坚

AI


大纲

进阶基础知识

ref(引用)

forwardRef

useImperativeHandle

useImperativeHandle 和 forwardRef 往往一起出现,但它们的职责是完全不同的层级

概述

React 的 useImperativeHandle 是一个 Hook,用来 自定义暴露给父组件的 ref 内容

换句话说:

基础语法

useImperativeHandle(ref, createHandle, [deps])

参数说明

场景示例:父组件控制子组件的行为

✅ 子组件(Child.tsx)

import React, { useImperativeHandle, useRef, forwardRef } from "react";

export interface ChildHandle {
  focusInput: () => void;
  reset: () => void;
}

const Child = forwardRef<ChildHandle>((_, ref) => {
  const inputRef = useRef<HTMLInputElement>(null);

  // 暴露给父组件的函数
  useImperativeHandle(ref, () => ({
    focusInput() {
      inputRef.current?.focus();
    },
    reset() {
      if (inputRef.current) inputRef.current.value = "";
    }
  }));

  return (
    <div>
      <input ref={inputRef} placeholder="请输入内容..." />
    </div>
  );
});

export default Child;

✅ 父组件(Parent.tsx)

import React, { useRef } from "react";
import Child, { ChildHandle } from "./Child";

export default function Parent() {
  const childRef = useRef<ChildHandle>(null);

  return (
    <div>
      <Child ref={childRef} />

      <button onClick={() => childRef.current?.focusInput()}>聚焦输入框</button>
      <button onClick={() => childRef.current?.reset()}>清空输入框</button>
    </div>
  );
}

📘 运行效果:

使用场景总结

场景 示例
操作子组件内部 DOM 例如父组件要聚焦子组件内部 input
调用子组件暴露的方法 例如子组件提供 reset、validate、scrollToBottom 等
封装复杂组件对外提供统一接口 例如封装富文本编辑器组件暴露 getHTML()、setHTML() 方法

Suspense

作用

用于异步加载组件(即懒加载)

原理

React Suspense 的工作原理基于一种新的渲染模式,称为“可中断的渲染”(Interruptible Rendering)。这一模式允许 React 暂停在某些组件上的渲染,并在这些组件准备好之后继续渲染。

以下是 Suspense 的核心机制:

  1. 异步边界

    当 React 渲染一个组件时,如果它遇到一个 Suspense 组件,并且 fallback 触发了,则会暂停该组件树的渲染。

  2. 资源的异步加载

    React.lazy 用于异步加载 React 组件。这些组件会在它们的模块加载完成之前暂停渲染。

  3. 数据的异步获取

    Suspense 可以与数据获取库结合使用。在这种情况下,React 会等待数据加载完成后再继续渲染。

  4. 缓存机制

    React 的新架构使用缓存来存储加载的数据或组件。这确保了相同的数据或组件在不同的渲染周期中可以被复用,减少了不必要的加载。

  5. 协调(Reconciliation) 和优先级调度

    React 的调度器会根据任务的优先级来协调更新。高优先级的任务(如用户交互)会优先处理,而低优先级的任务(如数据获取)会被延迟处理。这种机制使得 React 可以在任务之间进行切换,提高应用的响应速度和性能。

常规

一个完整的示例,包括: ✅ 懒加载 Header.tsx 和 Footer.tsx ✅ 使用 React.lazy ✅ 使用 Suspense 包裹 ✅ 含 fallback(加载中提示)

目录结构

src/
 ├── App.tsx
 ├── Header.tsx
 ├── Footer.tsx
 └── main.tsx

Header.tsx

export default function Header() {
  return <header style={{ background: "#eee", padding: "10px" }}>🌟 Header</header>;
}