使用无状态功能组件与调用方法有什么区别

What's the difference between using a stateless functional component versus calling a method?

本文关键字:方法 调用 什么 区别 组件 状态 功能      更新时间:2023-09-26

我试图理解无状态组件以及这些示例之间的区别:

class App {
  render() {
    return (
      <div>
        {this.renderAFunction('hello')}
      </div>
    );
  }
  renderAFunction(text) {
    return (
      <p>{text}</p>
    );
  }
}

而这个:

class App {
  render() {
    return(
      <div>
        <RenderAFunction text='hello'/>
      </div>
    );
  }
}
const RenderAFunction = ({text}) => (
    <p>{text}</p>
);

或者是否有任何区别?

在功能上,绝对没有区别。两者都最终呈现了一个段落元素,但还有其他方面需要考虑。在检查这两种方法时,有三点需要说明(在我看来(:

  • 可重用性:您必须了解在需要时分离组件。如果renderAFunction只是为了生成一些基于(例如 API 请求(的 JSX,那么在方法中就可以了。但是,如果您想在其他地方重用它,请将其分离到它自己的组件中。React 的很大一部分是组件可重用性和摆脱代码重复。必须将该方法分离到它自己的组件中才能实现此目的。
  • 目的:有理由使用无状态函数组件,也有理由不使用。无状态功能组件的全部意义在于没有状态并且是表示性的。如果你需要做一些涉及 React 生命周期或内部状态的事情,请保留它作为一个方法或新类,这取决于你是否希望它可重用。
  • 性能:使用无状态功能组件的效率会降低。这是因为它是一个组件,而不仅仅是从方法返回的一些 JSX。截至目前,React 团队计划对无状态功能组件进行一些优化,因为它们不包含状态,只是表示性的,但这可能不会在 React Fiber 完成之前发生,因此您的无状态功能组件与常规的成熟类组件相比没有优化。这使得它与返回一些JSX的方法相比效率非常低,特别是如果它只是在另一个组件中使用一次。

一个好的经验法则是问问自己,我在其他任何地方都需要它吗?如果没有,则将其保留在方法中。如果你在其他任何地方都不需要它,那么将 JSX 分成一个单独的组件会更差的性能,并且不会遵循 React 的核心原则。

如果你要在其他地方需要它,那么将组件分开,这样你就会遵循 React 的可重用性概念。

您的App's render函数将转换为以下 JS 代码作为您的第一个示例:

render() {
   return React.createElement(
     'div',
     null,
     this.renderAFunction('hello')
   );
 }

下面是第二个:

render() {
  return React.createElement(
    'div',
    null,
    React.createElement(RenderAFunction, { text: 'hello' })
  );
}

虽然它们看起来几乎相同,但有一个显着的区别:懒惰React 仅在要挂载到 DOM 层次结构的情况下执行RenderAFunction主体。

这是微不足道的,但成像以下示例:

const LazyApp = () => {
  const heavy = <div><HeavyStuff /></div>
  // ...
  return <div>done it</div>
}
const HardWorkingApp = () => {
  const heavy = <div>{HeavyStuff()}</div>
  // ...
  return <div>done it</div>
}
const HeavyStuff = () => {
  // ... do heavy rendering here
}

懒惰的应用程序根本不会执行任何繁重的事情。也许从这个综合例子中还不清楚为什么人们会做这样的事情。但是有现实世界的例子,当概念上相似的事情(创建Components而不渲染它们(正在发生时。

基本上,两者都将服务于相同的目的。但是创建组件的真正优势是它的可重用性。

如果您必须仅为此组件渲染该特定 jsx 部分。然后,无需创建单独的组件。