React Component & their Lifecycle

Saurabh Pandey
3 min readOct 3, 2023

--

In React, a component is a reusable piece of the UI. It can be thought of as a function that takes in parameters, called props, and returns a React element, which describes how a section of the UI should appear. Components can be written as either class components or functional components.

When creating a React component, the component’s name MUST start with an upper case letter.

Functional Components

Functional components are simply JavaScript functions. They receive data as a parameter (props) and return what looks like JSX code, which describes the UI.

Functional components are simpler and easier to read, especially for smaller components. With the introduction of React Hooks, they can also manage state and side effects.

Example

import React, { useState, useEffect } from 'react';

function Counter() {
const [count, setCount] = useState(0);

useEffect(() => {
document.title = `Count: ${count}`;
}, [count]);

const increment = () => {
setCount(prevCount => prevCount + 1);
}

return (
<div>
<button onClick={increment}>Increment</button>
<p>Count: {count}</p>
</div>
);
}

export default Counter;

In the example with hooks:

We use the useState hook to manage the state of the counter.

We use the useEffect hook to manage the side effect of updating the document title whenever the counter changes.

In React, the useEffect hook allows you to perform side effects in function components. Side effects could be things like data fetching, DOM manipulations, setting up subscriptions, or manually updating components.

Here’s a breakdown of what useEffect does:

  1. Combines Lifecycle Methods: In class components, you have lifecycle methods like componentDidMount, componentDidUpdate, and componentWillUnmount. The useEffect hook can mimic the behavior of all of these combined.
  2. Runs After Render: The effects inside useEffect run after the render is committed to the screen, ensuring that it doesn’t block the rendering process.
  3. Re-run Based on Dependencies: You can specify when the useEffect should re-run by providing a dependency array. If the values in this array remain unchanged between renders, the effect won’t run.
  4. Cleanup: If your effect returns a function, React will run it when it is time to clean up. This is useful for effects that create subscriptions or other resources that need to be cleaned up to prevent memory leaks.

Examples:

Mimicking componentDidMount (runs only once after the initial render):

useEffect(() => { console.log("Component did mount!"); }, []);

Here, the empty dependency array ([]) ensures the effect runs only after the component’s initial render.

Mimicking componentDidUpdate (runs after the initial render and every subsequent render):

useEffect(() => { console.log("Component did update!"); });

Without a dependency array, the effect runs after every render.

Mimicking componentDidMount and componentDidUpdate for specific state/prop changes:

useEffect(() => { console.log("Count value changed!"); }, [count]);

The effect only runs when the count value changes.

Mimicking componentWillUnmount (cleanup):

useEffect(() => { 
const subscription = someDataSource.subscribe();
// Cleanup function:
return () => { subscription.unsubscribe(); }; },
[]);

The returned function inside the useEffect will be called when the component is about to unmount, allowing you to clean up resources.

The returned function inside the useEffect will be called when the component is about to unmount, allowing you to clean up resources.

Class Components

Class components, as the name suggests, are ES6 classes that extend from React.Component. They include a render() method that returns the UI description.

Take the below example for class component.

import React, { Component } from 'react';

class Counter extends Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}

componentDidMount() {
document.title = `Count: ${this.state.count}`;
}

componentDidUpdate() {
document.title = `Count: ${this.state.count}`;
}

componentWillUnmount() {
// called when component is being removed from DOM.
}

increment = () => {
this.setState(prevState => ({ count: prevState.count + 1 }));
}

render() {
return (
<div>
<button onClick={this.increment}>Increment</button>
<p>Count: {this.state.count}</p>
</div>
);
}
}

export default Counter;
  • Mounting (e.g., constructor, componentDidMount): Called when the component is being created and inserted into the DOM.
  • Updating (e.g., shouldComponentUpdate, componentDidUpdate): Called when the component is re-rendering due to changes to either its props or state.
  • Unmounting (e.g., componentWillUnmount): Called when the component is being removed from the DOM.

--

--