In this post, we are going to create a simple React application to manage user information. Each user has three properties: an id, a name, and an age. The application will display a list of users with options to edit and delete their details.
When an admin clicks the edit button next to a user, the button will change to a save button, allowing the admin to save any changes made. The edit and delete buttons will return after saving.
Additionally, there will be a form at the top of the page where the admin can enter new user details and add them to the existing list.
The focus of this post is to demonstrate how a child component (User) can update the state of its parent component (UsersInfo), allowing us to efficiently manage user data and interactions within our application.
Follow below step-by-step procedure to build the working application.
Step 1: Go to the post (Quickly Set Up a React Project with Vite: A Step-by-Step), and set up a React Project ‘child-update-parent-state’.
Project structure looks like below.
Step 2: Create components folder in src/ folder and define User and UsersInfo component.
User.jsx
import { useState } from "react";
export default function User({ user, setUsersInfo }) {
const [editEnabled, setEditEnabled] = useState(true);
const [userInfo, setUserInfo] = useState(user);
return (
<>
<h1>User Details</h1>
{editEnabled && (
<ul>
<li>id : {userInfo.id}</li>
<li>username : {userInfo.name}</li>
<li>age : {userInfo.age}</li>
</ul>
)}
{!editEnabled && (
<div>
<p>
<label htmlFor="id">ID : </label>
<input id="id" type="text" value={userInfo.id} disabled />
</p>
<p>
<label htmlFor="username">Username : </label>
<input
type="text"
id="username"
value={userInfo.name}
onChange={(event) => {
setUserInfo((currentUser) => ({
...currentUser,
name: event.target.value,
}));
}}
/>
</p>
<p>
<label htmlFor="age">Age : </label>
<input
type="text"
id="age"
value={userInfo.age}
onChange={(event) => {
setUserInfo((currentUser) => ({
...currentUser,
age: Number(event.target.value), // Ensure age is treated as a number
}));
}}
/>
</p>
<br /> <br />
<button
onClick={() => {
setUsersInfo((currentUsers) =>
currentUsers.map((currentUser) => {
if (currentUser.id === userInfo.id) {
return {
...currentUser,
name: userInfo.name,
age: userInfo.age,
};
}
return currentUser;
})
);
setEditEnabled(true);
}}
>
Save
</button>
</div>
)}
{editEnabled && (
<div>
<button
onClick={() => {
setEditEnabled(false);
}}
>
Edit
</button>
<button
onClick={() => {
setUsersInfo((currentUsers) =>
currentUsers.filter(
(currentUser) => currentUser.id !== userInfo.id
)
);
}}
>
Delete
</button>
</div>
)}
</>
);
}
UsersInfo.jsx
import User from "./User";
import { useState } from "react";
export default function UserList({ users }) {
const [usersInfo, setUsersInfo] = useState(users);
const [username, setUsername] = useState("");
const [age, setAge] = useState("");
return (
<>
<form
onSubmit={(event) => {
event.preventDefault();
// Validate the input fields before adding a user
if (!username || !age) {
alert("Username and Age are required!");
return;
}
if (isNaN(age)) {
alert("Age must be a number");
return;
}
if (age < 18 && age > 60) {
alert("Age must be in between 18 and 60");
}
setUsersInfo((currentUsers) => {
const newId = currentUsers.length + 1;
return [
...currentUsers,
{ id: newId, name: username, age: Number(age) }, // Ensure age is a number
];
});
// Clear input fields after user is added
setUsername("");
setAge("");
}}
>
<label htmlFor="username">Username : </label>
<input
type="text"
id="username"
value={username}
onChange={(event) => {
setUsername(event.target.value);
}}
/>
<label htmlFor="age">Age : </label>
<input
type="text"
id="age"
value={age}
onChange={(event) => {
setAge(event.target.value);
}}
/>
<button type="submit">Add User</button>
</form>
{usersInfo.map((user) => (
<div key={user.id}>
<User user={user} setUsersInfo={setUsersInfo} />
</div>
))}
</>
);
}
Above code demonstrates a React application where users can be managed using edit, delete, and add functionalities. The application is structured into two components.
1. User Component (User.jsx)
2. UsersInfo Component (UsersInfo.jsx)
1. User Component (User.jsx)
This component is responsible for displaying the details of a single user, along with buttons to edit or delete that user. It also allows the admin to save any changes made.
State Management
1. editEnabled: A boolean state that toggles between viewing and editing mode for a user.
2. userInfo: Stores the current user's data (id, name, and age). It starts with the data passed as props from the parent component.
UI Logic
1. When editEnabled is true, the user's details (id, name, age) are displayed in read-only mode.
2. When editEnabled is false, editable input fields appear, allowing the user to update their details.
3. The save button updates the user's information in the parent component's state using the setUsersInfo function passed from the parent. This ensures changes are reflected globally.
Event Handlers
1. Edit Button: Switches the form to editing mode.
2. Delete Button: Removes the current user from the list by calling setUsersInfo to filter out the user with the matching ID.
3. Save Button: Saves the changes made by the user to the parent state (UsersInfo) by mapping over the current users and updating the relevant user’s data.
2. UsersInfo Component (UsersInfo.jsx)
This component manages the entire list of users and provides a form to add new users. It also renders individual User components for each user in the list.
State Management
1. usersInfo: Stores the list of all users, initialized with the data passed from the users prop.
2. username and age: Input fields for adding a new user.
Form Handling
At the top of the component, there is a form where the admin can enter a new username and age. When the form is submitted.
1. Input validation ensures the fields are not empty, age is a number, and the age falls between 18 and 60.
2. If valid, the new user is added to the usersInfo array with a new ID.
3. After adding a user, the form fields are cleared for convenience.
Rendering User Components
For each user in the usersInfo array, the User component is rendered. The setUsersInfo function is passed as a prop to enable child components to update the parent component’s state.
Step 3: Update main.jsx like below.
main.jsx
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import UsersInfo from "./components/UsersInfo";
let users = [
{
id: 1,
name: "Krishna",
age: 36,
},
{
id: 2,
name: "Ram",
email: "ram@abc.com",
age: 37,
},
];
createRoot(document.getElementById("root")).render(
<StrictMode>
<UsersInfo users={users} />
</StrictMode>
);
Step 4: Build and run the Application by executing below commands.
cd child-update-parent-state npm install npm run dev
You will see below kind of screen.
Try to experiment with the interaction provided in the above user interface to understand the application better.
You can download this application from this link.
Previous Next Home
No comments:
Post a Comment