何时使用基于ES6类的React组件vs.功能性ES6 React组件?

在花了一些时间学习React之后,我明白了创建组件的两种主要范式之间的区别。

我的问题是什么时候应该使用哪个,为什么?其中一种与另一种相比有什么好处/权衡?


ES6类:

import React, { Component } from 'react';


export class MyComponent extends Component {
render() {
return (
<div></div>
);
}
}

功能:

const MyComponent = (props) => {
return (
<div></div>
);
}

我认为函数是指没有状态可以被那个组件操纵的情况,但真的是这样吗?

我想,如果我使用任何生命周期方法,最好使用基于类的组件。

114194 次浏览

只要可能,总是尝试使用无状态函数(功能组件)。在某些情况下,你需要使用一个常规的React类:

  • 组件需要维护状态
  • 组件重新渲染太多,你需要通过shouldComponentUpdate来控制它
  • 你需要一个容器组件

更新

现在有一个名为PureComponent的React类,你可以扩展(而不是Component),它实现了自己的shouldComponentUpdate,为你处理浅道具比较。阅读更多

新回答:下面的大部分都是真的,直到React Hooks的引入。

  • componentDidUpdate可以用useEffect(fn)复制,其中fn是在重新呈现时运行的函数。

  • componentDidMount方法可以用useEffect(fn, [])复制,其中fn是在重新呈现时运行的函数,而[]是组件将重新呈现的对象数组,当且仅当自上次呈现以来至少有一个对象的值发生了变化。由于没有,useEffect()在第一次挂载时运行一次。

  • state可以用useState()复制,它的返回值可以被解构为状态的引用和可以设置状态的函数(即const [state, setState] = useState(initState))。举个例子可以更清楚地解释这一点:

const Counter = () => {
const [count, setCount] = useState(0)


const increment = () => {
setCount(count + 1);
}


return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>+</button>
</div>
)
}


default export Counter

说句题外话,我听过很多人因为性能原因而讨论不使用功能组件,特别是这个原因

“事件处理功能在每次渲染的功能组件中被重新定义”;

尽管如此,请考虑你的组件是否真的以这样的速度或体积渲染,这将是值得关注的。

如果是,你可以防止使用useCallbackuseMemo钩子重新定义函数。然而,请记住,这可能会使你的代码(微观)表现较差

但说实话,我从未听说过重新定义函数会成为React应用程序的瓶颈。过早的优化是万恶之源——当它成为一个问题时,要担心这一点。


你的想法是对的。如果你的组件只包含一些道具和渲染,那就使用功能性组件。您可以将它们看作纯函数,因为给定相同的道具,它们将始终呈现和表现相同。此外,它们不关心生命周期方法或拥有自己的内部状态。

因为它们是轻量级的,所以将这些简单组件编写为功能组件是相当标准的。

如果你的组件需要更多的功能,比如保持状态,请使用类。

更多信息:https://facebook.github.io/react/docs/reusable-components.html#es6-classes

2019年3月更新

在我最初回答的基础上:

React函数和React函数之间有什么根本的区别吗 还上课吗?当然,心智模型中也有-

< a href = " https://overreacted。Io /how-are-function-components-different-from-classes/" rel="nofollow noreferrer">https://overreacted.io/how-are-function-components-different-from-classes/

2019年2月更新:

随着反应钩子的引入,React团队似乎希望我们尽可能使用函数式组件(这更好地遵循了JavaScript的函数式本质)。

他们的动机:

  1. 很难在组件之间重用有状态逻辑。
  2. 复杂的组件变得难以理解。
  3. 课程让人和机器都感到困惑。

带有钩子的函数组件可以做类组件可以做的所有几乎事情,没有上面提到的任何缺点。

我建议你尽快使用它们。

原来的答案

功能组件并不比基于类的组件更轻量级,“它们完全像类一样执行”。——https://github.com/facebook/react/issues/5677#issuecomment-241190513

上面的链接有点过时了,但是React 16.7.0的文档说 函数和类组件:

从React的角度来看是等价的吗

https://reactjs.org/docs/components-and-props.html#stateless-functions

功能组件和只实现呈现方法的类组件本质上没有区别,只是语法不同。

今后(引用上述链接):

我们React可能会添加这样的优化

如果您试图通过消除不必要的渲染来提高性能,这两种方法都可以提供支持。memo用于功能组件,PureComponent用于类。

https: / / reactjs.org/docs/react-api.html # reactmemo

https: / / reactjs.org/docs/react-api.html # reactpurecomponent

这完全取决于你。如果你想要更少的样板文件,那就使用功能。如果你喜欢函数式编程,不喜欢类,那就选择函数式编程。如果您希望代码库中的所有组件保持一致,请使用类。当你需要类似state这样的东西时,如果你厌倦了从函数组件重构到基于类的组件,那就用类吧。

在React 17中,术语无状态函数组件是误导性的,应该避免使用(反应。香港证监会弃用Dan Abramov在React上说。香港证监会),它们可以有状态,也可以有钩子(充当生命周期方法),它们或多或少与类组件重叠

基于类的组件

功能组件:

为什么我更喜欢功能性组件

  • React提供了useEffect钩子,这是一种非常清晰和简洁的方式来组合componentDidMountcomponentDidUpdatecomponentWillUnmount生命周期方法
  • 通过钩子,你可以提取出可以轻松跨组件共享可测试的的逻辑
  • 减少对范围的混淆

React 动机解释为什么使用钩子(即功能组件)。

使用functional表单更简单,因为可以重用表单输入字段,还可以使用React显示条件将它们分开。

类是一个不能分解或重用的大组件。它们更适合于功能丰富的组件,比如在弹出式模块中执行算法的组件。

最佳实践是功能组件的可重用性,然后使用小的功能组件来组装完整的部分,例如,表单输入字段导入到React表单的文件中。

另一个最佳实践是在执行此操作的过程中不要嵌套组件。

我在生产中使用了大量的功能组件。我只在“错误边界”中使用过一次类组件。因为没有其他的“错误边界”可供选择。在功能组件中。

我使用“类组件”;实际上只有一次。

基于类的组件提供了一种更加结构化和有组织的方式来定义和实现组件,并且它们提供了额外的特性和功能,例如使用本地状态和生命周期方法的能力。这可以使它们成为创建需要大量逻辑和功能的复杂组件的好选择。

另一方面,功能组件更简单,更容易使用,而且它们的性能更高,因为它们更轻量级。它们也更容易测试和调试,因为它们是纯函数,没有副作用。这使得它们成为创建不需要大量逻辑或状态管理的简单组件的好选择。