React之PropsWithChildren

半兽人 发表于: 2025-04-02   最后更新时间: 2025-04-02 19:01:56  
{{totalSubscript}} 订阅, 18 游览

在 React 中,React.PropsWithChildren 是一个 TypeScript 类型工具,它用来为组件的 props 类型自动添加 children 属性。它的主要作用是简化类型定义,尤其当你的组件需要支持 children 时。

React.PropsWithChildren 的定义

PropsWithChildren 是一个泛型类型,定义在 React 的类型声明中,大致如下:

type PropsWithChildren<P = unknown> = P & {
  children?: ReactNode;
};
  • P:表示你自定义的 props 类型(可以是任意接口或类型)。
  • children?: ReactNode:表示 children 属性是可选的,类型是 ReactNode
    • ReactNode 是一个非常宽泛的类型,可以是 JSX 元素、字符串、数字、数组、null、undefined 等,几乎涵盖了所有可以在 React 中渲染的内容。

通过 PropsWithChildren,你可以在自定义 props 类型的基础上,自动获得 children 的类型支持。

怎么用

React.PropsWithChildren 通常在 TypeScript 项目中与 React 组件一起使用。以下是具体用法:

示例 1:基本用法

假设你有一个组件需要接收 name 属性,并且可能有 children

import React from 'react';
import type { PropsWithChildren } from 'react';

interface MyComponentProps {
  name: string;
}

// 使用 PropsWithChildren 扩展 props 类型
const MyComponent: React.FC<PropsWithChildren<MyComponentProps>> = ({ name, children }) => {
  return (
    <div>
      <p>Name: {name}</p>
      {children}
    </div>
  );
};

// 使用组件
<MyComponent name="Alice">
  <span>Hello, world!</span>
</MyComponent>;
  • PropsWithChildren<MyComponentProps>:将 MyComponentProps(只有 name)扩展为包含 children 的类型。
  • 结果:props 类型变成了 { name: string; children?: ReactNode }

示例 2:不使用 FC

如果你不使用 React.FC(因为现代趋势推荐避免隐式 children),可以直接用 PropsWithChildren 定义类型:

import React from 'react';
import type { PropsWithChildren } from 'react';

interface MyComponentProps {
  name: string;
}

function MyComponent({ name, children }: PropsWithChildren<MyComponentProps>) {
  return (
    <div>
      <p>Name: {name}</p>
      {children}
    </div>
  );
}

// 使用组件
<MyComponent name="Alice">
  <span>Hello, world!</span>
</MyComponent>;
  • 这里直接在函数参数中使用了 PropsWithChildren<MyComponentProps>,效果相同。

示例 3:没有自定义 props

如果你的组件只接收 children,不需要其他 props,可以直接用 PropsWithChildren<{}>

import React from 'react';
import type { PropsWithChildren } from 'react';

const Wrapper: React.FC<PropsWithChildren<{}>> = ({ children }) => {
  return <div>{children}</div>;
};

// 使用组件
<Wrapper>
  <p>This is inside the wrapper!</p>
</Wrapper>;

或者更简洁地:

import React from 'react';
import type { PropsWithChildren } from 'react';

function Wrapper({ children }: PropsWithChildren<{}>) {
  return <div>{children}</div>;
}

PropsWithChildrenFC 的关系

  • React.FC 内置了 PropsWithChildren:当你使用 React.FC<MyComponentProps> 时,children 已经被隐式包含在类型中了,所以你不需要额外使用 PropsWithChildren
  • 区别:如果你不用 FC,而是手动定义类型,PropsWithChildren 就很有用,因为它能显式地为你添加 children

为什么用 PropsWithChildren

  1. 类型安全:确保 children 的类型正确,避免手动定义出错。
  2. 简洁性:避免每次都手动写 { children?: ReactNode }
  3. 灵活性:可以与任何自定义 props 类型组合使用。

注意事项

  • 可选性children 是可选的(?:),所以组件不一定需要接收子节点。
  • 现代趋势:如果你完全不想要隐式 children,可以避免使用 FCPropsWithChildren,直接定义精确的 props 类型。

总结

React.PropsWithChildren 是一个方便的 TypeScript 工具,用于为组件的 props 添加 children 支持。它特别适合需要接收子节点的组件,常见于布局组件(如 Wrapper)或容器组件。使用时,只需将你的 props 接口传入它的泛型参数即可。

更新于 2025-04-02

查看React更多相关的文章或提一个关于React的问题,也可以与我们一起分享文章