Today, I was updating one of the existing React components in our Kustomer web codebase to prefetch saved search graph data upon a property change. Our existing React component appeared to be a class component like below:
export class SearchLayout extends React.Component<React.PropsWithChildren<SearchLayoutProps>> {
componentDidMount() {
// Component logic...
}
componentDidUpdate() {
// Component logic..
}
render() {
<div>
{ /* Render component */ }
</div>
}
}
Up until this point, I knew that you could create React components either by extending React.Component class or simply creating a function like below:
export default function SearchLayout(props: SearchLayoutProps) {
// Component logic..
return (
<div>
{ /* Render component */ }
</div>
);
}
As someone still relatively new to web development, I immediately realized something was wrong when I tried adding the useEffect()
hook to our class component. It turns out, this is not even supported with React class components and that’s what I learned today. I decided to do more research about the history and differences between two styles and share my findings..
React Class Components
An example Class Component in react.dev:
import { Component } from 'react';
class Greeting extends Component {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}
According to the docs:
- A
return() {}
has to be specified. - The props can be accessed via
this.props
. React hooks
are not supported!- Component state managed by internal
this.state
andthis.setState()
. - Has lifecycle methods such as:
componentDidMount()
: Component is added to the screencomponentDidUpdate()
: Component rerenders due to props or state changescomponentWillUnmount()
: Component is removed from the screencomponentDidCatch()
: Component threw an error
React Function Component
An example function component in react.dev
function Greeting({ name }) {
return <h1>Hello, {name}!</h1>;
}
According to the docs:
- Supports React Hooks like
useState()
anduseEffect()
- Properties (
props
) can be directly accessed via function parameters. - State is managed via hooks such as
useState()
instead ofthis.state
. - Does not rely on traditional lifecycle methods. Instead, hooks like useEffect() handle side effects.
Verdict
According to the official documentation, it is recommended to convert all class components into function components.
Before React hooks were introduced, if your component had a state or if you wanted utilize the lifecycle methods, you had to use a class component. Over time, different React hooks were added such as
useState()
which allowed you retain state in a function component.useEffect()
which changes the whole lifecycle methodology for the good. These changes were also similar to how Jetpack Compose (declarative UI library for Android) introduced new state changes. Essentially,useEffect()
accepts a parameter and the lambda function is triggered when that state changes.useContext()
allows you to read and subscribe to context within your application.- Creating custom hooks by both using
useState()
anduseEffect()
React Hooks offer significantly more functionality and flexibility compared to class component lifecycle methods. They make components more extensible and adaptable to future updates, whereas class components are now considered legacy.Thus, we should strive to use function components going forward.
Stay tuned for more articles, happy coding!