Skip to content

React 常用内置函数

lazy( )

该方法用于懒加载导入一个组件

懒加载导入的子组件在渲染时必须被内置组件<Suspense\>包裹

tsx
import type { FC } from "react";
import { lazy } from "react";

import 普通组件 from "组件路径";
import LoadingComponent from "组件路径";

// 默认导出的组件
const 懒加载组件1 = lazy(() => import("组件路径"));
// 命名导出的组件
const 懒加载组件2 = lazy(() => import("组件路径").then((module) => ({ default: module.组件名 })));

const 组件: FC = () => {
  return (
    <>
      <Suspense fallback={<LoadingComponent />}>
        <懒加载组件1 />
        <懒加载组件2 />
      </Suspense>

      <普通组件 />
    </>
  );
};

startTransition( )

该方法用于在当前组件范围内对状态的更新进行一个优先度降级

可用于解决耗时的状态更新会阻塞后续状态更新的问题

功能相当于内置钩子函数useTransition()

不能用于处理表单文本的连续输入,状态更新的优先度降级会导致快速连续的输入内容被覆盖

tsx
import type { FC } from "react";
import { startTransition, useState, useCallback } from "react";

const 组件: FC = () => {
  const [状态, set状态] = useState<状态的数据类型>(状态的初始值); 

  const 更新状态 = useCallback(() => {
    startTransition(() => set状态(新值));
  }, []);

  return (
    <>
      {/* 渲染内容 */}
      {/* 渲染内容 */}
    </>
  );
};

memo( )

该函数用于将一个组件转换为缓存组件

缓存组件会通过浅比较来检查组件参数props的变化,来避免不必要的组件重新渲染

tsx
import type { NamedExoticComponent } from "react";

const 组件: NamedExoticComponent = memo(() => {
  return (
    <>
      {/* 渲染内容 */}
      {/* 渲染内容 */}
    </>
  );
});

createContext( )

该方法用于创建一个可以在组件间深层传递数据的上下文对象

下文对象中 Context Provider 组件包裹的深层子组件内可获取更新传递的数据

深层子组件内通过内置钩子函数useContext()获取上下文传递的数据

tsx
import type { FC } from "react";
import { createContext, useContext } from "react";

const 上下文对象 = createContext<传递的数据的类型>(默认值);       

const 组件: FC = () => {
  const 缓存的数据 = useMemo<传递的数据的类型>(() => 数据, [依赖项]);

  return (
    <上下文对象.Provider value={缓存的数据}>
      <子组件 />
      <子组件 />
    </上下文对象.Provider>
  );
};

const 子组件: FC = () => {
  const 传递的数据 = useContext<传递的数据的类型>(上下文对象);

  if (!传递的数据) {
    // 当前组件没有被上下文 Provider 组件包裹时的处理
    // ...
  }

  return (
    <>
      {/* 渲染内容 */}
      {/* 渲染内容 */}
    </>
  );
};

React 19 新变化

  • React 18 及之前版本中,必须使用<上下文对象.Provider>组件包裹后代子组件
  • React 19 中可以使用<上下文对象>来代替 ( 上下文对象首字母必须大写 )

forwardRef( )

TODO:

createPortal( )

该方法用于创建一个传送门 ( Portal ) 将一些 JSX 渲染到当前组件以外的其他 DOM 上

tsx
import type { FC } from "react";
import { createPortal } from "react";

const 组件: FC = () => {
  return (
    <>
      {createPortal(            
        <>
          {/* 渲染内容 */}
          {/* 渲染内容 */}
        </>,
        目标DOM节点元素,
        唯一标识ID,
      )}
    </>
  );
};
例子:利用 Portal 指定 JSX 要渲染在哪里
tsx
import type { FC } from "react";
import { createPortal } from "react";

const elementID = "content-wrapper";

const ContentWrapperComponent: FC = () => {
  return <div id={elementID} />;
};

const ContentComponent: FC = () => {
  return (
    <>
      {createPortal(
        <p>Hello World</p>,
        document.getElementById(elementID)
        elementID,
      )}
    </>
  );
};

自定义事件模拟 Protal 组件的卸载

Portal 容器组件使用 CSS 属性display来控制显示隐藏时,作为渲染内容的组件没有卸载行为所以无法通过常规useEffect()来监控,此时可以在 Portal 目标容器组件内注册一个自定义事件,然后监听该事件来实现监控组件卸载的效果

tsx
 import type { FC } from "react";
 import { createPortal } from "react";

 const elementID = "content-wrapper";
 const customEventName = "CUSTOM_EVENT_NAME";

 const ContentWrapperComponent: FC = () => {
   const isShowProtal = useStateOfContentWrapperComponent();

   useEffect(() => {                                               
     if (!isShowProtal) {
       const event = new CustomEvent(customEventName);
       document.getElementById(elementID)?.dispatchEvent(event);
     }
   }, [isShowProtal]);

   return (
     <div
       id={elementID}
       style={{ display: isShowProtal ? "block : "none" }}
     />
   );
 };

 const ContentComponent: FC = () => {
   useEffect(() => {                                               
     const doSomething: VoidFunction = () => { /* ... */ };
     const elementContainer = document.getElementById(elementID)
     elementContainer?.addEventListener(customEventName, doSomething);
     return () => {
       elementContainer?.removeEventListener(customEventName, doSomething);
     };
   }, []);

   return (
     <>
       {createPortal(
         <p>Hello World</p>,
         document.getElementById(elementID),
         elementID,
       )}
     </>
   );
 };