当前位置: 首页 > 知识库问答 >
问题:

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

颜嘉福
2023-10-11

用的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

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

共有5个答案

赵永逸
2023-10-11

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

曹成双
2023-10-11

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

党佐
2023-10-11

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

function MyView({ children }: { children?: ReactNode}) {  return <div>{children}</div>;}
狄誉
2023-10-11

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

班安平
2023-10-11

这两种写法并不完全一样。在第一种情况下,你定义了一个带有 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 编译器不再报错。

 类似资料:
  • react 在 A 函数设置了state 然后调用 B函数,B函数中使用了state,但直接获取state不是最新值。 使用Effect和通过函数参数传递来解决,感觉都不优雅,大佬们有没有比较好的经验?

  • 最近看react fiber的文章,大致了解了fiber的一些原理,但也有个疑惑, 因为diff对比可以中断,假设在diff对比过程中用户有输入行为,这时候会优先执行输入这个任务,这个任务又会导致第二次diff对比,那么就有2次diff了,假设第一次diff要把输入框的内容改为1,第二次diff是要把输入框内容改为2,因为第二次diff优先级高,那么最终经过2次渲染,输入框的内容变成了1,和正常预

  • 父组件 子组件 为什么执行getSonData的时候,无法获取到子组件的data?sonRef.value.data只能在onMounted内使用吗?不能在父组件的方法里执行?

  • React中的useCallback 下面的代码中Com是父组件,Button是子组件,子组件接收父组件的count2和setCount2,子组件中使用了memo(Button)导出 子组件Button 在上面的代码中,如果点击count1++的按钮(不使用useCallback),父组件会重新渲染,但是子组件也会刷新,然而子组件中的count2依赖没有变化,所以只能是handleClick2函数

  • 个人背景:对网络传输刚刚有一定概念 在浏览器访问网页的过程中,tcp 和 ip 传输协议下,我们需要进行三次握手。 了解到三次握手的本质也是发送了数据包到对方电脑 问题1:既然我三次握手也是发包,那我为什么不干脆一开始就直接发数据包呢?(省去三次握手,直接发不是更快吗?) 问题2:TCP 实际上干了什么才导致“三次握手以后的发包,和不进行握手直接发包”有了区别? (不需要解释底层原理,希望可以举个

  • RefHandle是子组件通过钩子useImperativeHandle中返回的对象类型声明,即抛给父组件中的ref上的属性的类型声明 为什么这个泛型是这样的, 这俩个泛型参数顺序不能更换, 我有点看不懂