React useEffect: A complete guide with examples
alakkadshaw
Posted on June 21, 2023
React useEffect is a powerful and essential hook that allows you to synchronize a component with external system.
Using the react useEffect in functional components you can do things like fetching data, interacting with DOM elements and subscribing to event listeners.
Thus useEffect hook is an integral part of react development
useEffect(setup, dependencies?)
or
useEffect(()=>{
// some function
},[/*dependencies array*/])
Dead Simple Chat allows you to easily add Chat to any React Application using powerful Javascript Chat API and SDK.
How to use useEffect
Call the useEffect
at the top of your component to declare an effect
import { useState, useEffect } from 'react';
import { createConnection } from './createConnection.js';
function ChatRoom({ roomId }) {
const [serverUrl, setServerUrl] = useState('https://localhost:3000');
useEffect(() => {
const connection = createConnection(serverUrl, roomId);
connection.connect();
return () => {
connection.disconnect();
};
}, [serverUrl, roomId]);
// ...
}
the useEffect function accepts two arguments:
- A function (also called as setup): that is the effect and
- An Array: An array containing dependencies
-
setup
: Setup is the function with your effects logic. Your setup might additionally call an cleaner function.
When the component is first add to the DOM, the react runs the setup function.
React runs the setup function will run on every re render, only if one of the dependencies has changed
When the setup function is run, react will first run the clean up function with old dependencies (if you provided the clean up function that is) and then run the setup function with new values
After the component is removed from the the DOM the react will run the clean up function for one last time.
- Optional dependencies: All the reactive values that are mentioned inside of the setup code.
Reactive values include props, functions and all variables that are declared inside your component body.
The list of dependencies must be a constant number of items, they should not change and they should be written in line in an array like
[dep1, dep2 dep3]
Using the Object.is
notification the react compares each item with its previous value.
If you omit the dependencies array react will run the useEffect
function after every re render of the component.
This can lead to unintended consequences and performance issues. To make it so that the useEffect
runs only once and if we don't
-
useEffect
returns undefined
Dead Simple Chat allows you to easily add Chat to any React Application using powerful Javascript Chat API and SDK.
Things to remember
-
useEffect
is a hook, so you cannot call it inside loops or conditions. You can only call the useEffect at the top of your component - If you are not trying to synchronize with some external system like APIs, database, local storage etc then you don't need to use useEffect
- When strict mode is on React will run one more the setup clean up cycle. If this causes a problem then you should implement a clean up function
- Effects only run on the client side they don't run on the server
- usually what happens is that the browser repaints the screen before process the state updates inside your effect
- If you want to block the browser from repainting the screen you need replace useEffect with useLayoutEffect
Dead Simple Chat allows you to easily add Chat to any React Application using powerful Javascript Chat SDK.
Some Salient Points
Connecting to an external system.
The systems like API, database, or third party libraries are displayed on the page. But these systems aren't controlled by react and hence are called external
If you want to connect your component to an external system, you can call useEffect at the top level of your component like so
import { useEffect } from 'react';
import { createConnection } from './chat.js';
function ChatRoom({ roomId }) {
const [serverUrl, setServerUrl] = useState('https://localhost:3000');
useEffect(() => {
const connection = createConnection(serverUrl, roomId);
connection.connect();
return () => {
connection.disconnect();
};
}, [serverUrl, roomId]);
// ...
}
this is how the system works
The useEffect accepts two arguments
A setup function with setup code (code that connects with the external resource) that connects to the system
1.a. The setup function returns a clean up function with clean up code that disconnects from the system
- A list of dependencies including every value that the component inside the functions
React will call your setup and clean up functions multiple times whenever it is necessary
These are the times your component might re render
- When the first time your setup code runs and your component is added to the page
- Every time your dependencies have changed when your component re renders
- First your clean up code runs with the old dependencies
- then your setup code runs with new props and state
- your clean up code runs a final time when your component is removed from the page
Let us see what is happening with our example above
When the chat Room component gets added to the pafge it will connect to the chat room with initial
serverURl
and roomIdIf either the serverUrl or the roomId Changes because of the re render. cause the user got to another chat room or the system connected the user to another server then the useEffect with disconnect from the previous server or room and connect to the new room
When the chat room component is removed from the page the useEffect will disconnect the server and the chat room one last time
To help you debug your application react will run the setup and cleanup functions again before the setup
If this causes visiable issues there is something wrong with your clean up function. The clean up function should stop or undo whatever the setup was doing
The rule of thumb is that the user should not be able to distinguish between the development where the setup clean up and setup is happening and in production where set up and clean up happens
Note: External system means any peice of code that is not controlled by react this could include
- A timer that is controlled with
setInterval()
setTimeout()
clearInterval()
etc - An event subscription using
window.eventListener()
andwindow.removeEventListener()
- third party animation library with an API like
animation.start()
andanimation.reset()
Dead Simple Chat allows you to easily add Chat to any React Application using powerful Javascript Chat API and SDK.
Example 1 Connecting to a chat server
In this example the ChatRoom component uses an Effect to stay connected to the external system. It uses roomId as an prop to identify a chat room. ServerUrl is the state variable.
Chat Room component has the useEffect hook to create a connection when the roomId or the serverURL changes
when the component is unmounted it disconnects from the server.
Lastly the component renders an input field for the server URL and a welcome message
*App.js
*
import { useState, useEffect } from 'react';
import { createConnection } from './chat.js';
function ChatRoom({ roomId }) {
const [serverUrl, setServerUrl] = useState('https://localhost:1234');
useEffect(() => {
const connection = createConnection(serverUrl, roomId);
connection.connect();
return () => {
connection.disconnect();
};
}, [roomId, serverUrl]);
return (
<>
<label>
Server URL:{' '}
<input
value={serverUrl}
onChange={e => setServerUrl(e.target.value)}
/>
</label>
<h1>This is the {roomId} room!</h1>
</>
);
}
export default function App() {
const [roomId, setRoomId] = useState('general');
const [show, setShow] = useState(false);
return (
<>
<label>
Choose the chat room:{' '}
<select
value={roomId}
onChange={e => setRoomId(e.target.value)}
>
<option value="cool">cool</option>
<option value="awesome">awesome</option>
<option value="movies">movies</option>
</select>
</label>
<button onClick={() => setShow(!show)}>
{show ? 'Close chat' : 'Open chat'}
</button>
{show && <hr />}
{show && <ChatRoom roomId={roomId} />}
</>
);
}
export function createConnection(serverUrl, roomId) {
// A real implementation would actually connect to the server
return {
connect() {
console.log('✅ Connecting to "' + roomId + '" room at ' + serverUrl + '...');
},
disconnect() {
console.log('❌ Disconnected from "' + roomId + '" room at ' + serverUrl);
}
};
}
Dead Simple Chat allows you to easily add Chat to any React Application using powerful Javascript Chat API and SDK.
Example 2: Using useEffect to track browsers pointer movement
In this example the external event is the browsers DOM. Normally you can have event listeners with the JSX. but you cannot listen to the global window object like this
An effect lets you connect to the window object and listen to the events
import { useState, useEffect } from 'react';
export default function App() {
const [position, setPosition] = useState({ x: 0, y: 0 });
useEffect(() => {
function handleMove(e) {
setPosition({ x: e.clientX, y: e.clientY });
}
window.addEventListener('pointermove', handleMove);
return () => {
window.removeEventListener('pointermove', handleMove);
};
}, []);
return (
<div style={{
position: 'absolute',
backgroundColor: 'pink',
borderRadius: '50%',
opacity: 0.6,
transform: `translate(${position.x}px, ${position.y}px)`,
pointerEvents: 'none',
left: -20,
top: -20,
width: 40,
height: 40,
}} />
);
}
We are importing the useState and useEffect hooks. these hooks lets us maintain state and take care of external effects in our component
The useEffect hook has a handleMove event listener function. It takes e as an argument and sets the position of clientx
and clienty
properties of the event object
which is the X and Y co ordinates of the mouse pointer. The useEffect hook adds an event listener function called the handleMove to the window
Object
that listens to the pointermove
events
Dead Simple Chat allows you to easily add Chat to any React Application using powerful Javascript Chat API SDK.
We also have a clean up funtion that removes the event listener when the component is unmounted
Lastly we have a div element with a pink semi transparent background that tracks where the pointer is moving
The element also has pointerEvents: none to avoid having the pointer interact with other element on the page
Conclusion
In this article we have explained how to use useEffect to connect to an external source ( and What we mean by external source: External source is something that is not controlled by the react like an API or a Database etc)
We also gave a few examples and explained what is the role of the clean up function and how the dependencies are required to be added in an array format to the setup
Thanks for reading the article
Note: This article was originally written on the DeadSimpleChat website: React useEffect: A complete guide with examples
Posted on June 21, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 8, 2024