关于react函数组件传children的疑问?

用的TypeScript。

我定义了一个函数组件:MyView:

type Props = {
  children?: React.ReactNode;
};

function MyView(props: Props) {
  const { children } = props;
  return <div>{children}</div>;
}

可以正常使用:

<MyView>{<div>sss</div>}</MyView>

为了看起简洁点,我将 MyView 稍微修改了一下:

function MyView(children?: React.ReactNode) {
  return <div>{children}</div>;
}

这个时候调用的地方就报错了:
image.png

报错信息:

Type '{ children: Element; }' is not assignable to type 'IntrinsicAttributes & ReactNode'.
Type '{ children: Element; }' is missing the following properties from type 'ReactPortal': key, type, props

我懵逼了,这两种写法难道不是一样的吗?怎么就报错了?前端萌新理解不了,希望有经验的大佬可以指点一下。

阅读 2k
avatarAI BotBETA

这两种写法并不完全一样。在第一种情况下,你定义了一个带有 props 参数的函数组件,其中 props 的类型是 Props 类型。Props 类型包含一个可选的 children 属性,其类型是 React.ReactNode

在第二种情况下,你定义了一个接受单个参数 children 的函数组件,该参数的类型也是 React.ReactNode。但是,你没有明确这个参数是函数的 props,而只是简单地定义了一个接受 children 参数的函数。

在 TypeScript 中,React 严格遵循函数组件的约定,即函数组件应该接受一个 props 对象作为其参数,并且应该以 props 作为其第一个参数。

当你尝试将一个 <div>sss</div> 作为 children 传递给新的 MyView 函数时,TypeScript 编译器会报错,因为这个 children 参数并没有明确它是 props 的一部分。它只是一个单独的参数,而不是 props 对象的一部分。

你可以通过将你的函数修改为以下形式来解决这个问题:

function MyView({ children }: { children?: React.ReactNode }) {
  return <div>{children}</div>;
}

这样,你明确地定义了一个 props 对象,其中包含一个可选的 children 属性。这就符合了 TypeScript 和 React 的约定,因此 TypeScript 编译器不再报错。

5 个回答

这里引用一下官方文档的描述 -> 将 Props 传递给组件
image.png
函数组件的参数列表和普通函数还是有区别的,不是我们随意定义的,而是由 React 提供的一个对象,原因也很简单,函数组件最终是由 React 去调用的,参数列表定义权在React而不在开发者

首先,组件的props是properties的缩写,英文是属性复数的意思,学习过html的都应该知道,
<div class="" id=""></div>
class和style都是标签的属性,所以将标签的属性转换为react的props就是
{ class: '', id: '' }

然后,使用react组件
<MyView>{<div>sss</div>}</MyView>
又可以写为
<MyView children={<div>sss</div>}></MyView>

现在你应该已经明白了react组件的唯一参数不能直接写children了,正确的写法为

function MyView({ children }: { children?: React.ReactNode }) {
  return <div>{children}</div>;
}

你定义的 MyView 函数参数是 children,而不是包含 children 属性的对象(也就是通常的 props)。因此,TypeScript 认为你想要的是直接接受一个 ReactNode 参数,而不是传递一个对象。
改成这样:

function MyView({ children }: { children?: ReactNode}) {
  return <div>{children}</div>;
}

props 在前端领域 基本接触到的都是一个对象 props : { children?: React.ReactNode }

注意区分普通函数和函数式组件,函数式组件的第一个参数是props,第一个参数是props,第一个参数是props,获取children要从props中解构出来。下图是函数式组件的接口定义:
image.png

推荐问题
logo
Microsoft
子站问答
访问
宣传栏