REACT:变量中的JSX与函数中的JSX以及单独的组件中的JSX

2022-03-02 00:00:00 reactjs javascript html jsx

要在较大的组件中呈现较小的组件/JSX,可以遵循多种方法。例如,请考虑以下内容:

方法1:

function BigComponent(props) {
  const renderSmallComponent1 = () => <div>{props.a}</div>;
  const renderSmallComponent2 = () => <div>{props.b}</div>;

  return (
    <div>
      {renderSmallComponent1()}
      {renderSmallComponent2()}
    </div>
  )
}

方法二:

function BigComponent(props) {
  const smallComponent1 = <div>{props.a}</div>;
  const smallComponent2 = <div>{props.b}</div>;

  return (
    <div>
      {smallComponent1}
      {smallComponent2}
    </div>
  )
}

方法3:

function SmallComponent1({ a }) {
  return <div>{a}</div>;
}

function SmallComponent2({ b }) {
  return <div>{b}</div>;
}

function BigComponent(props) {
  return (
    <div>
      <SmallComponent1 a={props.a} />
      <SmallComponent2 b={props.b} />
    </div>
  )
}

我只是想了解这三个方面的区别

  • 开发经验,
  • 框架如何处理它们,
  • 有没有性能优化,
  • 所有这些组件的运行时行为是否都有差异?
  • 在某些情况下使用哪一个更好?

以下是我的理解:

  • 在方法3中,所有SmallComponent都是在另一个组件中呈现的Reaction组件,因此它们有一个组件生命周期,而在方法1和2中,它们是简单的JSX,没有生命周期,所以它们不会作为Reaction组件挂载/卸载
  • 在方法2中,我们会急于计算JSX,因为它直接是一个变量,而在方法1中,只有在Render中调用函数时才会计算它。因此,如果我们有任何条件渲染,那么急切的求值可能只是浪费。

其他几篇有用的文章:

  • https://medium.com/missive-app/45-faster-react-functional-components-now-3509a668e69f
  • https://kentcdodds.com/blog/dont-call-a-react-function-component

更新:观察结果1似乎不正确,因为它们全部3仍将呈现为Reaction组件,因此将具有组件生命周期。因此Reaction将装入/卸载它们。

更新2:不,观察%1是正确的,方法%1和%2都被视为BigComponent的一部分的常规JSX,并且它们没有被视为具有生命周期的反应组件。

更新3: 还有另一种方法方法4:

function BigComponent(props) {
  const SmallComponent1 = () => {
  return <div>{props.a}</div>;
  }
  const SmallComponent2 = () => {
  return <div>{props.b}</div>;
  }

  return (
    <div>
      <SmallComponent1 />
      <SmallComponent2 />
    </div>
  )
}

这类似于方法3,但在通过开发工具进行调试时,方法3与方法4在执行方面略有不同。


解决方案

方法二:

function BigComponent(props) {
  const smallComponent1 = <div>{props.a}</div>;
  const smallComponent2 = <div>{props.b}</div>;

  return (
    <div>
      {smallComponent1}
      {smallComponent2}
    </div>
  )
}
  • 如果您希望将大UI分成多个小UI,此方法将为您提供最佳性能,因为
    • 它仍然只是一个大的UI组件。
    • Reaction只需解析变量引用。
    • 重新呈现时,BigComponent、SmallComponent1和SmallComponent2一起呈现为单个单元。
    • SmallComponent1和SmallComponent2不能有自己的状态、生命周期和挂钩。
    • SmallComponent1和%2需要在每次更改BigComponent1和2状态时重新初始化。因此,如果这些小组件的结果来自昂贵的计算,最好用useMemo()包装它们。

方法3:

function SmallComponent1({ a }) {
  return <div>{a}</div>;
}

function SmallComponent2({ b }) {
  return <div>{b}</div>;
}

function BigComponent(props) {
  return (
    <div>
      <SmallComponent1 a={props.a} />
      <SmallComponent2 b={props.b} />
    </div>
  )
}
  • Reaction需要解析引用并在解析引用后执行函数。

  • 它是将Reaction的实际子组件组合成一个大组件。

  • 允许子组件拥有自己的hooks

  • 子组件不会重新初始化,但如果更改了BigComponent状态,则会重新呈现。

  • 如果小组件根据父级中的道具更改更新其自身状态,则SmallComponent1和SmallComponent2有可能在BigComponents呈现上多次重新呈现一次。

  • 如果每个SmallComponent都应该使用多个状态为BigComponent的道具,则将SmallComponents保留在BigComponent之外确实可以提供良好的开发体验。

  • 希望通过以上几点也能理解方法1和方法4。

  • 注意:如果您的应用程序逻辑使用ref或DOM元素来维护呈现的焦点或锚点,则存储在变量和子组件中的子组件作为函数会变得很棘手。

相关文章