We all know that there are two types of components in React.
1. class components
2. function components
Before React 16.8, function components were stateless.
However, with the introduction of hooks in React 16.8,Function components became capable of having state and lifecycle methods (here I am referring to lifecycle methods using hooks).
The ability to share stateful logic independent of UI rendering logic made function components popular among React developers. With function components, we can do almost everything possible with class components.
Then why does ReactJS still have class components?
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.
Top comments (22)
Because they want to maintain backwards compatibility and they are still working on updating the docs (see the beta docs)
@brense Just FYI
shouldComponentUpdate
method, which is extremely dirty and has historically resulted in many headaches and developers losing the will to live.useEffect
hook. It's developer nature I guess... Not taking the time to really understand how things are supposed to work.-In my article i said that we cannot create (not use) error boundaries with functional components.
What happens under the hood clearly make this true.
Wanting to create error boundaries is GOOD a reason to go for class-based components,because we can't in fact create error boundaries with function components.
-As you said "If the unpure parent keeps rerendering, so will the children",and that's the exact case where need to use pure component. Because see memoization(React.memo) will only work for props,and its only make shallow comparison by default.
Memoization works for all state. It allows you to only rerender the parent if the state you're interested in has actually changed. This results in less rerenders of parent and children. Pure components can't hold any state, only props. This meant in practice that people would move the state up to the parent component to artificially keep its children "pure". Because there is no momoization in class components this meant that the parent would rerender more frequently because it was controlling more state and any state change would trigger a rerender of the parent and all of it's fake "pure" children. In the modern day, we learned that its better to keep state as low in the tree as possible so it doesn't trigger unnecessary rerenders in the parent.
"Pure components can't hold any state, only props." Have you confirmed this?
As far i know,React.PureComponent is similar to React.Component (AS per the react doc).So they can have state.But for React.memo as i can read in the doc
React.memo is not the only memoization technique in React hooks... useMemo and useCallback are the memoization hooks you want to be using.
This is all you need to know about Pure components: deprecated beta.reactjs.org/reference/react/P...
For useMemo i already said,everything outside callback will be executed when component will be re-rendered.Now the problem with useMemo is that dependencies are compared shallowly (by reference not by value ),
for example if some one pass an array in dependency and at certain stage if reference of array is changed (i.e array being updated by API call but value still remains the same),then useMemo will cause re-render.
For "Pure components: deprecated ",I have read the link you shared, And have you noticed ? They are teaching how to use PureComponent in React.In that link they clearly says "Class components are still supported by React, but we donβt recommend using them in new code".Then why they are teaching how to use PureComponent?? (Please dont say "to maintain backwards compatibility")
When they are not recommend using them in new code??
And the best part is that they are referring React.memo instead useMemo in that link instead ,even React.memo is not the only memoization technique in React hooks.
Everything everywhere in React has always been and always will be shallow compared. This was also the case with React class components unless you wrote your own custom
shouldComponentUpdate
. All I can tell you is... Don't change the reference to your array if you don't mean to change it... If you do, you want your component to rerender and your useMemo that depends on the array to be executed. This is how React has always worked. If you dont want your component to respond to your array when it changes, you should use theuseRef
hook.Yes that's what backwards compatibility means... Dont use in new projects, but you can upgrade your old projects to new react version, without breaking your old class components.
Everything everywhere in React has always been and always will be shallow compared. This was also the case with React class components unless you wrote your own custom
shouldComponentUpdate
. All I can tell you is... Don't change the reference to your array if you don't mean to change it... If you do, you want your component to rerender and your useMemo that depends on the array to be executed. This is how React has always worked. If you dont want your component to respond to your array when it changes, you should use theuseRef
hook.Yes that's what backwards compatibility means... Dont use in new projects, but you can upgrade your old projects to new react version, without breaking your old class components.
Yes React.memo is what people tend to use instead of pure components. React.memo and useMemo are not the same thing though. useMemo affects the state of your component while React.memo just memoizes your component similarly to how useCallback works for callbacks inside your component.
"This was also the case with React class components unless you wrote your own custom shouldComponentUpdate."
-And that's the case we need class component.
"All I can tell you is... Don't change the reference to your array if you don't mean to change it".
-Is it even possible?
Yes?
Thanks for reading!
Interesting that there are still edge cases where class based components are needed!
Thanks for reading!
There are not I think this is an article written a few years ago and published now.
Thanks for reading!
LOL nice, so we're even getting info that's outdated :-P
Yep seems like it. Don't use class components pleaseπ
No definitely not ... that's why I was rather surprised by this post :-D