React道具:我应该传递对象还是它的属性?这有多大区别



在传递道具时,我应该将整个对象传递到子组件中,还是应该先在父组件中单独创建道具,然后将这些道具传递给子组件?

通过整个对象:

<InnerComponent object={object} />

单独创建首先需要的道具:

<InnerComponent name={object.name} image={object.image} />

哪一个是首选,如果需要,我应该用什么作为衡量标准?

根据最小特权原则,这是一种正确的方式:

<InnerComponent name={object.name} image={object.image} />

这限制了InnerComponent意外修改原始对象或访问不适合它的属性

或者,属性可以从原始对象中提取并作为道具传递:

<InnerComponent {...pick(object, 'name', 'image')} />

如果有许多属性需要列出,那么可能只有一个道具可以接受一个对象:

<InnerComponent object={pick(object, 'name', 'image')} />

您应该更喜欢第二个例子,单独传递道具。在那里,您可以明确地看到传递了哪些参数,并可以快速地与预期的参数进行比较。这使得人们之间的协作更加容易,并使应用程序的状态更加清晰。

如果不需要的话,我个人尽量避免传递整个对象。这就像spread操作符,里面可以有任何属性,在更大的范围内调试要困难得多。

对纯反应的一些添加,如prop-typestypescript,可能有助于在大型应用中定义清晰和预期的属性

由于JavaScript没有类型注释,第二种选择会更好,正如@mstuebing所提到的,代码将更易于维护。然而,如果您使用的是TypeScriptReact(支持类型注释),那么这两种选择都同样清晰。但请记住,第一选择促进了视图和模型之间的紧密耦合,这允许快速开发,因为您不必键入太多;而第二种选择可能会减慢开发速度,但您对未来的变化有更高的灵活性和容忍度。

因此,衡量标准是:如果你更喜欢开发速度而不是灵活性,那么选择1;如果您更喜欢灵活性而不是开发速度,请选择第2项。

额外注释

好的,什么时候我们应该更喜欢开发速度而不是灵活性?这是我的2美分。

如果你的项目是短期使用的(例如,开发一个只用于在选举期间收集选票的应用程序),那么就选择第一个。

如果你的项目是长期使用的(例如在线银行交易门户),你应该选择第二个。

将多个道具传递给一个子组件是将道具传递给子组件的首选方式。这将帮助您跟踪子组件中应用程序的状态。此外,请随时使用prop-types模块。它的作用类似于Java中的泛型,并为要传入的道具提供类型安全性

如果您没有使用对象中的所有属性,最好单独传递所需的属性,因为当Child组件是使用shouldComponentUpdatePureComponent时,这有助于性能优化。在这种情况下,只有当Child组件使用的道具发生更改时,它才会重新渲染,而不是当对象中未使用的属性发生更改时。

然而,如果您正在使用对象中的所有属性,那么如果您将对象作为道具传递下去,只要您正确处理对象的突变,就不会有太大的不同。

我同意其他答案,简而言之,这取决于,其他答案中提出的观点都是有效的。

我想补充的其他一些点也倾向于使用单独的属性,如下所示-

  • 有时甚至不是我是否需要所有属性的问题?这应该是一个更大的问题——我是否希望将组件的使用限制在只有完整对象而不仅仅是属性子集的情况下

以显示汽车图像、品牌和型号的小部件为例,将其作为小部件列表的一部分,期望完整的Car类型可用以仅显示汽车的图像、品牌或型号是不合理的。只需要这3个属性。

  • 随着graphql等的兴起,我们可以限制返回的关于类型的数据的属性,我们不应该总是假设组件可以访问基于类型的完全填充的对象。

  • 最后,在导致不必要的组件重新发布到树下的问题上,总是传递完整的对象,您可能会导致所有使用该对象的子对象在对象更新时都会重新发布。然而,将单独的属性传递给子级(通常是基元),我们可以更好地减少不必要的重发

对象的全部目的是将类似的属性封装在一起。如果您有大约10个属性,并且希望在子组件中使用它们,请使用对象。

但在您的情况下,我的意见是使用您的第二个示例,因为它使子组件中的代码更简单。

为了两全其美,只需销毁子组件中所需的道具。

像这样:

function InnerComponent({ name, image }) {
...
}

如果你不喜欢参数中的大括号,请这样做:

function InnerComponent(props) {
const { name, image } = props;
...
}

它取决于该对象。是否需要将其所有属性传递给另一个组件?或您可能需要将5个属性中的2个传递给特定组件?

  • 如果您不需要传递它的所有属性,我建议您传递将Properties作为Props
  • 但是,如果你100%确定你需要所有的财产一起传递,我建议将整个Object作为Props传递这种情况下,因为它会是更清晰的代码,让你远离忘记传东西了。例如添加新特性时对于那个对象,你不必传递它,因为你已经在传递了整个对象

如果您不确定该对象的当前/未来用途,因为您可能需要很快排除一些属性,那么在这种情况下,您可能应该单独传递其属性,而不是将一些未使用的属性传递给其他组件。

您可以使用React.createElement函数将props作为单个对象传递到JSX元素中。

因为每个JSX元素只是调用React.createElement的语法糖。

以下两条线对于React是相等的:

<Button variant={"secondary"}>Add</Button>
{React.createElement(Button, {variant: "secondary", children: "Add"})}

最新更新