admin管理员组文章数量:1129779
After spending some time learning React I understand the difference between the two main paradigms of creating components.
My question is when should I use which one and why? What are the benefits/tradeoffs of one over the other?
ES6 classes:
import React, { Component } from 'react';
export class MyComponent extends Component {
render() {
return (
<div></div>
);
}
}
Function:
const MyComponent = (props) => {
return (
<div></div>
);
}
I’m thinking function component 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.
After spending some time learning React I understand the difference between the two main paradigms of creating components.
My question is when should I use which one and why? What are the benefits/tradeoffs of one over the other?
ES6 classes:
import React, { Component } from 'react';
export class MyComponent extends Component {
render() {
return (
<div></div>
);
}
}
Function:
const MyComponent = (props) => {
return (
<div></div>
);
}
I’m thinking function component 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.
Share Improve this question edited Jan 2 at 6:40 Drew Reese 202k17 gold badges228 silver badges264 bronze badges asked Mar 19, 2016 at 4:47 omarjmhomarjmh 13.9k6 gold badges36 silver badges42 bronze badges 11 | Show 6 more comments9 Answers
Reset to default 313New Answer: Much of the below was true, until the introduction of 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:
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
As a small aside, I have heard a number of people discussing not using functional components for the performance reasons, specifically that
"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.
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.
Old Answer: 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.
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
UPDATE Jan 2023
TLDR; Functions are the best way to create components. React.Component
is a legacy API.
"We recommend defining components as functions instead of classes."
"Class components are still supported by React, but we don’t recommend using them in new code."
https://react.dev/reference/react/Component
UPDATE March 2019
Building on what was stated in my original answer:
Are there any fundamental differences between React functions and classes at all? Of course, there are — in the mental model.
https://overreacted.io/how-are-function-components-different-from-classes/
UPDATE Feb 2019:
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).
Their motivation:
- It’s hard to reuse stateful logic between components.
- Complex components become hard to understand.
- Classes confuse both people and machines.
A functional component with hooks can do almost everything 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 (April 2018)
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
The above link is a little dated, but React 16.7.0's documentation says that functional and class components:
are equivalent from React’s point of view
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
If you're trying to boost performance by eliminating unnecessary renders, both approaches provide support. memo
for functional components and PureComponent
for classes.
https://reactjs.org/docs/react-api.html#reactmemo
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.
Always try to use stateless functions (functional components) whenever possible. There are scenarios where you'll need to use a regular React class:
- 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
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
As of React 17 the term Stateless Functional components is misleading and should be avoided (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
Class based components
- state
- lifecycle methods
- memoization with React.PureComponent
Functional components:
- state (useState, useReducer hooks)
- lifecycle methods (via the useEffect, useLayoutEffect hooks)
- memoization via the memo 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 shared across components and testable
- less confusion about the scoping
React motivation on why using hooks (i.e. functional components).
I have used functional components for heavily used application which is in production. There is only one time I used class components for "Error Boundaries" because there is no alternative "Error Boundaries" in functional components.
I used "class component" literally only one time.
Class-based components offer a more structured and organized way to define and implement a component, and they provide additional features and capabilities, such as the ability to use local state and lifecycle methods. This can make them a good choice for creating complex components that require a lot of logic and functionality.
On the other hand, functional components are simpler and easier to work with, and they can be more performant because they are more lightweight. They are also easier to test and debug, because they are pure functions that don't have side effects. This makes them a good choice for creating simple components that don't require a lot of logic or state management.
Despite Having so many useful features in function components, There are some cases in which we need to use the Class component over the Function component:
1. Error boundary
When an error occurs usually it displays a component tree that crashed on screen, it can leave a bad impression on the end-user.
Error boundaries help us deal with this situation. Error boundaries allow us to display fallback UI when an error occurs inside a component.
We can use error boundaries to trace client-side errors and provide useful information for debugging. It's not possible to create an error boundary with a function component.
Error boundaries can only be implemented with class components.
2. Pure Component
Many times, we need to avoid unnecessary re-rendering of components depending on certain criteria.
In such cases, We can use pure components by extending React.PureComponent, as they have a static method "shouldComponentUpdate" that decides whether to re-render or not based on the component's props and state.
Many times react js developers use the "useMemo" hook to avoid unnecessary re-rendering like this :
const App=()=>{
return useMemo(()=>{
return <>{/*Code*/}</>
},[dependancies])
}
However, everything before the "useMemo" hook will still be executed when the component updates its state. Therefore, "useMemo" may not always be the best option for avoiding unnecessary re-rendering.
Since we cannot create pure components with function components, we will need to use class components.
3. Life Cycle methods
I know This should not be the case, because most lifecycle methods like componentDidMount, componentDidUpdate, or componentWillUnmount can be replaced with useEffect.
It is important to note that the useEffect hook requires some extra care when it comes to dependencies and avoiding infinite loops.
One has to be very careful about dependency. and make sure dependency is not updated from inside the hook (this can lead to an infinite loop)
In a class component, the lifecycle methods are executed automatically when certain events occur, such as when the component is mounted, updated, or unmounted.
I think using functional method as it can.
We recommend defining components as functions instead of classes. See how to migrate.
read more(React dev document)
This is what is written on Reacts official website. Now to summarize why to use functional components over class components.
- Simpler syntax: Functional components are easier to read, write, and maintain.
- Hooks: Enable state and lifecycle features in functional components, making them just as powerful as class components.
- No this: Avoids confusion and bugs related to the this keyword.
- Reusability: Hooks promote reusable and modular code.
- Performance: Functional components with hooks like React.memo offer easier performance optimizations.
- Future-proof: Functional components align with the future direction of React.
版权声明:本文标题:javascript - When to use ES6 class based React components vs. ES6 React function components? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736718241a1949322.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
const MyComponent = (props) => <div>...</div>
– Viliam Simko Commented Aug 15, 2017 at 10:57