Javascript 何时使用基于 ES6 类的 React 组件与功能性 ES6 React 组件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/36097965/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
When to use ES6 class based React components vs. functional ES6 React components?
提问by omarjmh
After spending some time learning React I understand the difference between the two main paradigms of creating components.
在花了一些时间学习 React 之后,我理解了创建组件的两种主要范式之间的区别。
My question is when should I use which one and why? What are the benefits/tradeoffs of one over the other?
我的问题是我什么时候应该使用哪一个,为什么?一个相对于另一个的好处/权衡是什么?
ES6 classes:
ES6 类:
import React, { Component } from 'react';
export class MyComponent extends Component {
render() {
return (
<div></div>
);
}
}
Functional:
功能:
const MyComponent = (props) => {
return (
<div></div>
);
}
I'm thinking functional whenever there is no state to be manipulated by that component, but is that it?
每当该组件没有要操纵的状态时,我都在考虑功能性,但就是这样吗?
I'm guessing if I use any life cycle methods, it might be best to go with a class based component.
我猜如果我使用任何生命周期方法,最好使用基于类的组件。
采纳答案by Jeff Cousins
You have the right idea. Go with functional if your component doesn't do much more than take in some props and render. You can think of these as pure functions because they will always render and behave the same, given the same props. Also, they don't care about lifecycle methods or have their own internal state.
你有正确的想法。如果您的组件除了接收一些 props 和渲染之外,没有做更多的事情,请使用函数式。您可以将它们视为纯函数,因为在给定相同的 props 的情况下,它们将始终呈现相同的行为。此外,他们不关心生命周期方法或拥有自己的内部状态。
Because they're lightweight, writing these simple components as functional components is pretty standard.
因为它们是轻量级的,所以将这些简单的组件编写为功能组件是非常标准的。
If your components need more functionality, like keeping state, use classes instead.
如果您的组件需要更多功能,例如保持状态,请改用类。
More info: https://facebook.github.io/react/docs/reusable-components.html#es6-classes
更多信息:https: //facebook.github.io/react/docs/reusable-components.html#es6-classes
EDIT: Much of the above was true, until the introduction of React Hooks.
编辑:上述大部分内容都是正确的,直到引入 React Hooks。
componentDidUpdate
can be replicated withuseEffect(fn)
, wherefn
is the function to run upon rerendering.componentDidMount
methods can be replicated withuseEffect(fn, [])
, wherefn
is the function to run upon rerendering, and[]
is an array of objects for which the component will rerender, if and only if at least one has changed value since the previous render. As there are none,useEffect()
runs once, on first mount.state
can be replicated withuseState()
, whose return value can be destructured to a reference of the state and a function that can set the state (i.e.,const [state, setState] = useState(initState)
). An example might explain this more clearly:
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
Regarding the recommendation on when to use class over functional components, Facebook officially recommends using functional components wherever possible. As a small aside, I have heard a number of people discussing not using functional components for the performance reasons, specifically that
关于何时使用类而不是功能组件的建议,Facebook 官方建议尽可能使用功能组件。顺便说一句,我听到很多人讨论出于性能原因不使用功能组件,特别是
"Event handling functions are redefined per render in functional components"
“事件处理函数在功能组件中为每个渲染重新定义”
Whilst true, please consider if your components are really rendering at such a speed or volume that this would be worth concern.
虽然是这样,但请考虑您的组件是否真的以如此值得关注的速度或体积渲染。
If they are, you can prevent redefining functions using useCallback
and useMemo
hooks. However, bear in mind that this may make your code (microscopically) worse in performance.
如果是,您可以防止使用useCallback
和useMemo
钩子重新定义函数。但是,请记住,这可能会使您的代码(微观上)性能更差。
But honestly, I have never heard of redefining functions being a bottleneck in React apps. Premature optimisations are the root of all evil - worry about this when it's a problem
但老实说,我从未听说过重新定义函数是 React 应用程序的瓶颈。过早的优化是万恶之源——当它出现问题时要担心
回答by ffxsam
Always try to use stateless functions (functional components) whenever possible. There are scenarios where you'll need to use a regular React class:
只要有可能,请始终尝试使用无状态函数(功能组件)。在某些情况下,您需要使用常规 React 类:
- The component needs to maintain state
- The component is re-rendering too much and you need to control that via
shouldComponentUpdate
- You need a container component
- 组件需要维护状态
- 该组件重新渲染太多,您需要通过
shouldComponentUpdate
- 你需要一个容器组件
UPDATE
更新
There's now a React class called PureComponent
that you can extend (instead of Component
) which implements its own shouldComponentUpdate
that takes care of shallow props comparison for you. Read more
现在有一个叫做 React 的类PureComponent
,你可以扩展(而不是Component
)它实现自己的shouldComponentUpdate
,为你处理浅层 props 比较。阅读更多
回答by Galupuf
UPDATE March 2019
2019 年 3 月更新
https://overreacted.io/how-are-function-components-different-from-classes/
https://overreacted.io/how-are-function-components-different-from-classes/
UPDATE Feb 2019:
2019 年 2 月更新:
With the introduction of React hooks, it seems as though the React teams wants us to use functional components whenever possible (which better follows JavaScript's functional nature).
随着React hooks的引入,React团队似乎希望我们尽可能使用函数式组件(这更好地遵循了 JavaScript 的函数式本质)。
Their motivation:
他们的动机:
1.) It's hard to reuse stateful logic between components
2.) Complex components become hard to understand
3.) Classes confuse both people and machines
A functional component with hooks can do almosteverything a class component can do, without any of the draw backs mentions above.
带有钩子的函数式组件几乎可以做类组件可以做的所有事情,而没有上面提到的任何缺点。
I recommend using them as soon as you are able.
我建议您尽快使用它们。
Original Answer
原答案
Functional components aren't any more lightweight than class based components, "they perform exactly as classes." - https://github.com/facebook/react/issues/5677#issuecomment-241190513
功能组件并不比基于类的组件更轻量级,“它们与类完全一样”。- https://github.com/facebook/react/issues/5677#issuecomment-241190513
The above link is a little dated, but React 16.7.0's documentation says that functional and class components:
上面的链接有点过时了,但是 React 16.7.0 的文档说函数和类组件:
"are equivalent from React's point of view." - https://reactjs.org/docs/components-and-props.html#stateless-functions
“从 React 的角度来看是等价的。” - https://reactjs.org/docs/components-and-props.html#stateless-functions
There is essentially no difference between a functional component and a class component that just implements the render method, other than the syntax.
除了语法之外,功能组件和仅实现渲染方法的类组件之间基本上没有区别。
In the future (quoting the above link) "we [React] might add such optimizations."
将来(引用上面的链接)“我们 [React] 可能会添加此类优化。”
If you're trying to boost performance by eliminating unnecessary renders, both approaches provide support. memo
for functional components and PureComponent
for classes.
如果您试图通过消除不必要的渲染来提高性能,两种方法都可以提供支持。memo
用于功能组件和PureComponent
类。
-https://reactjs.org/docs/react-api.html#reactmemo
- https://reactjs.org/docs/react-api.html#reactmemo
-https://reactjs.org/docs/react-api.html#reactpurecomponent
- https://reactjs.org/docs/react-api.html#reactpurecomponent
It's really up to you. If you want less boilerplate, go functional. If you love functional programming and don't like classes, go functional. If you want consistency between all components in your codebase, go with classes. If you're tired of refactoring from functional to class based components when you need something like state
, go with classes.
这真的取决于你。如果您想要更少的样板,请使用功能。如果你喜欢函数式编程而不喜欢类,那就去函数式编程吧。如果您希望代码库中所有组件之间保持一致性,请使用类。如果您厌倦了在需要类似的东西时从函数式组件重构为基于类的组件state
,请使用类。
回答by Karim
As of React 16.8 the term Stateless Functional components is misleading and should be avoided cause they are not anymore stateless (React.SFC deprecated, Dan Abramov on React.SFC), they can have a state, they can have hooks (that act as the lifecycle methods) as well, they more or less overlap with class components
从 React 16.8 开始,无状态功能组件这个术语具有误导性,应该避免,因为它们不再是无状态的(React.SFC 已弃用,Dan Abramov 在 React.SFC 上),它们可以有状态,它们可以有钩子(充当生命周期方法)以及它们或多或少与类组件重叠
Class based components
基于类的组件
- state
- lifecycle methods
- memoization with React.PureComponent
- 状态
- 生命周期方法
- 使用React.PureComponent记忆
Functional components:
功能组件:
- state (useState, useReducerhooks)
- lifecycle methods (via the useEffect, useLayoutEffecthooks)
- memoization via the memoHOC
- 状态(useState,useReducer钩子)
- 生命周期方法(通过useEffect, useLayoutEffect钩子)
- 通过备忘录HOC 进行记忆
Why i prefer Funtional components
为什么我更喜欢函数式组件
- React provide the useEffect hook which is a very clear and concise way to combine the
componentDidMount
,componentDidUpdate
andcomponentWillUnmount
lifecycle methods - With hooks you can extract logic that can be easily sharedacross components and testable
- less confusion about the scoping
- React 提供了 useEffect 钩子,这是一种非常清晰简洁的方式来组合
componentDidMount
,componentDidUpdate
和componentWillUnmount
生命周期方法 - 使用钩子,您可以提取可以在组件之间轻松共享和可测试的逻辑
- 减少对范围界定的混淆
React motivationon why using hooks (i.e. functional components).
反应动机为什么使用钩子(即功能组件)。