DrillLab
第 59 / 105 道59 / 105 · #322

函数组件 vs 类组件

Functional components vs Class components

先自己答,再往下看Answer it yourself first

一句话:现在一律写函数组件。 类组件只在维护老代码和写错误边界时才用 (错误边界目前还只能用 class)。

类组件函数组件
状态this.state / setStateuseState
副作用生命周期方法useEffect
this要处理绑定没有 this,不存在这问题
逻辑复用HOC / render props(嵌套很深)自定义 hook(平铺)
代码量

为什么官方推函数组件—— 答这三条比列表格更有说服力:

  • 逻辑能按关注点组织, 而不是按生命周期切碎。 类组件里「订阅」和「取消订阅」被迫分在componentDidMountcomponentWillUnmount 两个方法里;useEffect 让它们写在一起
  • 复用逻辑不用套娃。HOC 叠三层就变成「wrapper 地狱」, 自定义 hook 是平的。
  • this 的问题彻底消失。

会追问:「函数组件里怎么拿 shouldComponentUpdate?」——React.memo, 但它默认是浅比较,需要自定义就传第二个参数。

In one line: write function components, always. Class components are for maintaining old code and for error boundaries, which still have to be classes.

Class componentFunction component
Statethis.state / setStateuseState
Side effectsLifecycle methodsuseEffect
thisYou deal with bindingNo this, so no such problem
Reusing logicHOC / render props (deep nesting)Custom hooks (flat)
Amount of codeMoreLess

Why the official line favours function components — these three points land better than the table:

  • Logic groups by concern instead of being sliced up by lifecycle. In a class, subscribing and unsubscribing are forced apart into componentDidMount and componentWillUnmount; useEffect lets them sit together.
  • Reusing logic needs no nesting. Three stacked HOCs turn into wrapper hell; custom hooks stay flat.
  • The this problem disappears completely.

Follow-up: “How do you get shouldComponentUpdate in a function component?” — React.memo, though it compares shallowly by default; pass a second argument when you need your own comparison.