This content originally appeared on Bits and Pieces - Medium and was authored by Nivetha Krishnan
React 18 introduces ‘Transition’ to improve the application responsiveness by optimizing the performance.
What is Transition?
React 18 has introduced a new concept called transition to help distinguish between urgent and non-urgent updates.
Urgent updates like typing, clicking, or pressing are expected to respond immediately on the screen.
Non—urgent updates are displaying the list of users, where a slight delay can be acceptable, and doesn’t expect to see every intermediate value on screen.
useTransition Hook:
React 18's new hook useTransition lets you update the state without blocking the UI.
Before deep diving into how to use the latest hook, let’s have a deeper understanding of the problem its solves.
Let’s Talk About the Problem
Consider an application where you render a huge list of users and a textbox to search any of the users by their names. Let’s imagine the following code component.
import React, { useState, useTransition } from 'react';
export default function App({ users }) {
const [searchUsers, setSearchUsers] = useState('');
const [filterUsers, setFilterUsers] = useState(users);
const handleChange = ({ target: { value } }) => {
setSearchUsers(value);
setFilterUsers(users.filter((item) => item.name.includes(value)));
};
return (
<div className="container">
<div>
{
users.length !== filterUsers.length
? `${filterUsers.length} matches`
: null
}
</div>
<input
onChange={handleChange}
value={searchUsers}
type="text"
placeholder="Type a name"/>
<div className="cards">
{filterUsers.map((user) => (
<div class="card">
<div className="profile">
<img
src={user.avatar}
alt="avatar" />
</div>
<div className="body">
<strong>{user.name}</strong>
</div>
</div>
))}
</div>
</div>
);
}
We have two states searchUsers and filterUsers. The searchUsers state will help manage the text, entered in the textbox to filter the user list. The filterUsers is the state variable for managing the filtered user list.
The handleChange is an event handler function for the search box so that we can handle the event every time someone types in it. Both the states are updated during this event handler. The first state update will update the search term value on the search textbox. The second state update will update the user list.
By default, all the state updates are urgent in React and both the state change occur almost simultaneously. React will batch the change and update them together which is the best feature of React. But what if we are dealing with a huge list of users? Here comes the problem
The first state change (searchUsers ) will take a short time to update the value on the search textbox, but the second state (filterUsers ) may take a long time to filter out the huge list of users. Since React batch and updates the changes together, the quicker state update will wait for the longer state to complete. This may lead to a situation where the typing in the search textbox will lag which is not a good user experience. The useTransitionis here to rescue.
Solution: The useTransition Hook
With this hook, we can specify any state update as non-urgent. These non-uregentstate updates will occur simultaneously with other urgent state updates, but the component rendering will not wait for the non-urgent state updates.
The useTransition hook Structure:
const [isPending, startTransition] = useTransition();
The useTransition hook returns an array with two elements:
isPending: It is a boolean-type variable that returns true when the second element startTransition executes and false when the execution is completed.
startTransition: A plain JavaScript function that takes a callback function as an argument that contains code related to non-urgent state updates.
Let’s now modify our code using the useTransition hook.
The first thing is to import the hook to use it.
import React, { useState, useTransition } from 'react';
const [isPending, startTransition] = useTransition();
Next, we have to modify the handleChange method where the state updation happens. Now we are marking the state change of the user-filtered list as non-urgent by placing it inside the callback function of startTransition.
const handleChange = ({ target: { value } }) => {
setSearchUsers(value);
startTransition(() => {
setFilterUsers(users.filter((item) => item.name.includes(value)));
});
};
The last thing is to update the isPending variable to ensure we show a loader when the startTransition function executes.
{isPending ? (
<div>Loading...</div>
) : (
<div className="cards">
{filterUsers.map((user) => (
<div class="card">
<div className="profile">
<img
src={user.avatar}
alt="avatar" />
</div>
<div className="body">
<strong>{user.name}</strong>
</div>
</div>
))}
</div>
)}
💡 Note: If you wanted to create custom hooks using useTransition and other react hooks, you can reuse them using Bit. Bit lets you publish, version, and reuse custom hooks across multiple projects with a simple bit import your.username/yourCustomHook command.
Learn more here:
How to reuse React components across your projects
The Complete Code:
import React, { useState, useTransition } from 'react';
export default function App({ users }) {
const [searchUsers, setSearchUsers] = useState('');
const [filterUsers, setFilterUsers] = useState(users);
const [isPending, startTransition] = useTransition();
const handleChange = ({ target: { value } }) => {
setSearchUsers(value);
startTransition(() => {
setFilterUsers(users.filter((item) => item.name.includes(value)));
});
};
return (
<div className="container">
<div>
{
isPending ? (
<div>Loading...</div>
) : (
<p>
{
users.length !== filterUsers.length
? `${filterUsers.length} matches`
: null
}
</p>
)
}
</div>
<input
onChange={handleChange}
value={searchUsers}
type="text"
placeholder="Type a name" />
{
isPending ? (
<div>Loading...</div>
) : (
<div className="cards">
{filterUsers.map((user) => (
<div class="card">
<div className="profile">
<img
src={user.avatar}
alt="Avatar" />
</div>
<div className="body">
<strong>{user.name}</strong>
</div>
</div>
))}
</div>
)}
</div>
);
}
Conclusion:
With the help of this hook, the component is improved to handle the non-urgent state updates and rendering much more effectively.
Build React Apps with reusable components, just like Lego
Bit’s open-source tool help 250,000+ devs to build apps with components.
Turn any UI, feature, or page into a reusable component — and share it across your applications. It’s easier to collaborate and build faster.
Split apps into components to make app development easier, and enjoy the best experience for the workflows you want:
→ Micro-Frontends
→ Design System
→ Code-Sharing and reuse
→ Monorepo
Learn more:
- Creating a Developer Website with Bit components
- How We Build Micro Frontends
- How we Build a Component Design System
- How to reuse React components across your projects
- 5 Ways to Build a React Monorepo
- How to Create a Composable React App with Bit
- How to Reuse and Share React Components in 2023: A Step-by-Step Guide
- 5 Tools for Building React Component Libraries in 2023
Understanding Transition in React 18 Using useTransition Hook was originally published in Bits and Pieces on Medium, where people are continuing the conversation by highlighting and responding to this story.
This content originally appeared on Bits and Pieces - Medium and was authored by Nivetha Krishnan
Nivetha Krishnan | Sciencx (2023-06-07T06:02:58+00:00) Understanding Transition in React 18 Using useTransition Hook. Retrieved from https://www.scien.cx/2023/06/07/understanding-transition-in-react-18-using-usetransition-hook/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.