React Hooks provides a powerful way to manage state and lifecycle events in functional components. However, if you’re transitioning from class components to functional components, you might miss the familiar lifecycle methods like componentDidMount
, componentDidUpdate
, and componentWillUnmount
.
Fortunately, you can achieve similar functionality using Hooks. Let’s explore how to mimic lifecycle methods with Hooks.
Prerequisites:
Steps To Create React Application and Installing Module:
Step 1: Create a new react app using the following command.
npx create-react-app my-react-app
Step 2: Navigate to the root directory of your project using the following command.
cd my-react-app
Project Structure:
project structure
The updated dependencies in package.json file will look like:
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
}
Mounting:
Mounting in React involves creating a component and rendering it onto the DOM. Here’s a concise breakdown for both class and functional components.
Mimicking constructor:
In class components, the constructor
method is used for initializing state and binding event handlers. In functional components, you can achieve similar behavior using the useState
Hook for state initialization and useRef
Hook for storing mutable values.
Syntax:
// In Class component
class MyComponent extends Component {
constructor(props) {
super(props);
// Your constructor logic here
}
}
// In Functional component
function createInstance(param1, param2) {
return {
param1: param1,
param2: param2,
};
}
const instance = createInstance("value1", "value2");
Mimicking componentDidMount:
In class components, componentDidMount
is invoked after the component is mounted and rendered. To achieve similar behavior in functional components, you can use the useEffect
Hook with an empty dependency array.
Syntax:
// In Class component
class MyComponent extends React.Component {
componentDidMount = () => {
// componentDidMount logic here
}
}
// In functional component
useEffect(() => { /* componentDidMount logic */ }, []);
Mimicking render:
The render
method in class components is responsible for rendering the component UI. In functional components, the main body of the component serves the same purpose.
Syntax:
// for class component
class MyClassComponent extends React.Component {
render() {
return <div>Render content here</div>;
}
}
// for functional component
const MyFunctionalComponent = () => {
<div>Render content here</div>;
}
Updating:
Whenever a component experiences alterations, it undergoes an update. These modifications can stem from changes in props or state. React furnishes built-in methods to manage updated components:
Mimicking componentDidUpdate:
componentDidUpdate
is triggered whenever props or state change. In functional components, you can use useEffect
with dependencies to achieve similar behavior.
Syntax:
// for class component
class MyClassComponent extends React.Component {
componentDidUpdate(prevProps) {
// componentDidUpdate logic here
}
}
// for functional component
const MyFunctionalComponent = ({ prop }) => {
useEffect(() => {
// componentDidUpdate logic here
}, [prop]);
};
Mimicking shouldComponentUpdate:
shouldComponentUpdate
allows class components to optimize rendering by preventing unnecessary re-renders. In functional components, you can achieve a similar effect using the React.memo
higher-order component combined with the useMemo
Hook.
// for class component
class MyClassComponent extends React.Component {
shouldComponentUpdate(nextProps, nextState) {
// shouldComponentUpdate logic here
return true; // or false based on your condition
}
}
// for functional component
const MyFunctionalComponent = React.memo(({ prop }) => {
// shouldComponentUpdate logic here
});
Unmounting:
When a component is removed from the DOM, it is considered unmounted. In this scenario, only one built-in method comes into play. These component lifecycles pertain exclusively to class components. However, functional components mimic some of these lifecycle methods using React hooks, chiefly useState()
and useEffect()
.
Mimicking componentWillUnmount:
In class components, componentWillUnmount
is used for cleanup tasks before a component unmounts. With Hooks, you can return a cleanup function from useEffect.
Syntax:
// for class component
class MyClassComponent extends React.Component {
componentWillUnmount() {
// componentWillUnmount logic here
}
}
// for functional component
const MyFunctionalComponent = () => {
useEffect(() => {
return () => {
// componentWillUnmount logic here
};
}, []);
};
Regarding the constructor:
In functional components, the constructor’s role is fulfilled by useState()
. Typically, the constructor initializes state values and binds the this
keyword for non-lifecycle methods. It executes prior to the component’s rendering.
In the provided example, the Greeting component employs three methods in the following order:
constructor
()
: It sets the initial state for “greeting” and binds the reference to this
within the setGreeting
method.
render
()
: This method determines the content to be displayed or returned by the component. Initially, it renders a button with an event listener and an empty paragraph.
- Upon clicking the button:
setGreeting
()
: This updates the greeting state from an empty string to “Hello GeeksforGeeks!“, prompting a re-render of the component.
render
()
: It runs again, displaying “Hello World!” in place of the previous empty string.
For functional components, equivalent functionality can be achieved using useState
()
:
Example: Below is an example to illustrate’s the implementation of lifecycle methods with class components in React.
Javascript
import React, { Component } from 'react' ;
class LifecycleExample extends Component {
constructor(props) {
super (props);
this .state = {
count: 0
};
console.log( 'Constructor called' );
}
componentDidMount() {
console.log( 'Component did mount' );
setTimeout(() => {
this .setState({
count: this .state.count + 1
});
}, 2000);
}
componentDidUpdate(prevProps, prevState) {
console.log( 'Component did update' );
console.log( 'Previous state:' , prevState);
console.log( 'Current state:' , this .state);
}
componentWillUnmount() {
console.log( 'Component will unmount' );
}
render() {
console.log( 'Render method called' );
return (
<div>
<h1>Lifecycle Example</h1>
<p>Count: { this .state.count}</p>
</div>
);
}
}
export default LifecycleExample;
|
Start your application using the following command.
npm start
Output:
Output
Example 2: Below is an example to illustrate’s the mimicking lifecycle methods with Hooks in React.
Javascript
import React, {
useState,
useEffect,
useRef
} from 'react' ;
const ExampleComponent = () => {
const [count, setCount] = useState(0);
const didMountRef = useRef( false );
useEffect(() => {
console.log( 'Component mounted' );
didMountRef.current = true ;
return () => {
console.log( 'Component will unmount' );
};
}, []);
useEffect(() => {
if (didMountRef.current) {
console.log( 'Component updated' );
} else {
didMountRef.current = true ;
}
}, [count]);
const shouldUpdateRef = useRef( true );
useEffect(() => {
if (shouldUpdateRef.current) {
console.log( 'Component will update' );
}
shouldUpdateRef.current = true ;
});
const handleClick = () => {
setCount(count + 1);
};
return (
<div>
<p>Count: {count}</p>
<button onClick={handleClick}>Increment</button>
</div>
);
};
export default ExampleComponent;
|
Start your application using the following command.
npm start
Output:
Output
Share your thoughts in the comments
Please Login to comment...