useEffect in reactjs

dinesh priyantha
3 min read3 days ago

--

useEffect is a hook in React that allows you to perform side effects in functional components. Side effects can include tasks like fetching data, manually changing the DOM, and setting up subscriptions or timers. It serves a similar purpose to lifecycle methods in class components such as componentDidMount, componentDidUpdate, and componentWillUnmount.

Here’s a comprehensive guide on how to use useEffect:

Basic Usage

Example: Running an Effect on Initial Render

import React, { useEffect } from 'react';

const MyComponent = () => {
useEffect(() => {
console.log('Component mounted');
// You can perform initial side effects here, like fetching data

return () => {
console.log('Component unmounted');
// Cleanup code goes here (e.g., clearing timers or subscriptions)
};
}, []); // Empty dependency array means this effect runs once on mount and cleanup on unmount

return <div>Hello, world!</div>;
};

export default MyComponent;

In this example:

  • The effect runs once after the initial render because the dependency array is empty.
  • The cleanup function runs when the component unmounts.

Dependencies

Example: Running an Effect When Dependencies Change

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

const MyComponent = ({ prop }) => {
const [count, setCount] = useState(0);

useEffect(() => {
console.log('Effect ran because prop or count changed');

return () => {
console.log('Cleanup when prop or count changes or component unmounts');
};
}, [prop, count]); // Effect runs when 'prop' or 'count' changes

return (
<div>
<p>Prop: {prop}</p>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
};

export default MyComponent;

In this example:

  • The effect runs whenever prop or count changes.
  • The cleanup function runs before the effect re-runs due to changes in dependencies and when the component unmounts.

No Dependency Array

Example: Running an Effect on Every Render

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

const MyComponent = () => {
const [count, setCount] = useState(0);

useEffect(() => {
console.log('Effect runs on every render');

return () => {
console.log('Cleanup on every render');
};
}); // No dependency array, so effect runs on every render

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

export default MyComponent;

In this example:

  • The effect runs on every render.
  • The cleanup function also runs on every render before the new effect runs.

Conditional Effects

Example: Running an Effect Conditionally

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

const MyComponent = () => {
const [count, setCount] = useState(0);

useEffect(() => {
if (count > 0) {
console.log('Effect runs when count is greater than 0');
}

return () => {
if (count > 0) {
console.log('Cleanup when count changes and was greater than 0');
}
};
}, [count]); // Effect runs when 'count' changes

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

export default MyComponent;

In this example:

  • The effect runs only if count is greater than 0.
  • The cleanup function also checks if count was greater than 0 before running.

Fetching Data

Example: Fetching Data on Mount

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

const DataFetchingComponent = () => {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);

useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch('https://api.example.com/data');
const result = await response.json();
setData(result);
} catch (error) {
console.error('Error fetching data:', error);
} finally {
setLoading(false);
}
};

fetchData();
}, []); // Empty dependency array, so fetch data on mount

if (loading) return <p>Loading...</p>;
if (!data) return <p>No data available</p>;

return <div>Data: {JSON.stringify(data)}</div>;
};

export default DataFetchingComponent;

In this example:

  • Data is fetched once when the component mounts.
  • The loading state is updated based on the fetch request's lifecycle.

Summary

  • useEffect: Used to perform side effects in functional components.
  • Dependencies: The second argument is an array of dependencies. The effect runs when any dependency changes.
  • Cleanup: The cleanup function runs before the effect re-runs and when the component unmounts.
  • Scenarios: Fetching data, setting up subscriptions, timers, logging, or manual DOM operations.

useEffect provides a powerful and flexible way to handle side effects in React functional components, mimicking the behavior of lifecycle methods in class components while leveraging React's declarative nature.

--

--