1

好奇在const设置组件的 props 时尽可能使用变量的性能或其他好处,而不是将它们设置为内联。如果适用,请包括支持 ReactJS 文档。

在我的脑海中使用 const 变量的潜在好处:

  • 减少在每次渲染时创建对象的开销。
  • 更少杂乱的代码?
  • 更少的生命周期/渲染循环?(这是我主要关心的问题。)

示例 1:内联/传统

export const SomeContainer(...) => (
  <Something validators={[required(), minLength(3), maxLength(10)]} />
);

示例 2:通过const变量

export const SomeContainer(...) => (
  <Something validators={Validators} />
);

const Validators = [required(), minLength(3), maxLength(10)];

示例 1中,validatorsprop 是每次渲染上的一个新数组,而在示例 2中,将一个常量值传递给validatorsprop。

同样的问题:

  • 内联与 const 对象...
    • value={{a, b, c}}
    • value={ConstWithABC}
  • 内联与 const 回调...
    • onChange={value => setState({ x: value })}
    • onChange={handleChange}handleChange是一个实例函数/const lambda)
4

2 回答 2

1

React 可以轻松跟踪状态变化。所以直接重新渲染状态所有者组件(我们称之为XComponent)是第一点。然后,正如您已经知道的那样,重新渲染流程将递归地在所有 XComponent 的子树上开始。

在执行此操作时,React 将检查prop更改以决定哪些孩子应该重新渲染,例如:

  1. 如果prop是原始的,将有一个简单的值比较

  2. 如果prop是数组、函数或对象(这就是您在问题中提到的地方),则会直接进行参考比较。这就是为什么为此目的有两个钩子:useMemouseCallback. 这些挂钩可帮助您存储来自组件内定义/计算的引用或值结果。因此,由于引用相等,您的第二个示例很可能不会触发重新渲染。然后 React 可以停止修剪重新渲染树<Something />及其可能的子节点。

prop我过去在更改数组项时遇到了这种情况。我看到 React 甚至没有意识到prop由于相同的数组引用,我将数组的长度从 3 更改为 2。但我看到屏幕上仍然有 3 个项目。

  1. 如果孩子是某些迭代或映射的结果,例如:
const Comp1 = (props) => {
  return <div>
    {props.data.map((item) => <Comp2 key={item.id} propX={item.x}/>)}
  </div>;
};

然后,将进行key比较,以了解应该从渲染中添加或删除哪个孩子。 https://reactjs.org/docs/lists-and-keys.html#keys React 文档建议您应该对键使用原始类型以使比较更容易。

总的来说,有一个文档可以更好地解释https://reactjs.org/docs/reconciliation.html

于 2020-11-21T20:19:14.537 回答
0

基本上你的例子都是值,我看不出有太大的性能差异。

但是,如果您执行以下操作,将会有所不同。

<Something value={[1000 numbers array].reduce((a,b) => a+b))} />

对比

const someNumber = useMemo(() => [1000 numbers array].reduce((a,b) => a+b)), [1000 numbers array])
return <Something value={someNumber} />

在上面的示例中,如果要渲染页面 1000 次,则计算 x 1000 与计算 x 1。

如果您不希望 const Validators = [...] 每次都重新渲染,您基本上可以将它作为全局 const 变量放在组件之外,并且只渲染一次。

例如,如果你想声明一个样式组件,总是建议在组件外部声明样式组件,这样你只渲染一次。

关于您的以下示例。

inline vs. const callbacks ...
onChange={value => setState({ x: value })}
onChange={handleChange} (handleChange is an instance function/const lambda)

您只是指单个 setState。如果它具有 100 行代码的功能怎么办?你要把它扔进退货条款吗?

很多时候,除了性能,我们还考虑可读性。即使在 return 子句中编写函数可以提供更好的性能,我也永远不会这样做。

于 2020-11-23T07:36:29.453 回答