I am creating CRUD Application using React to manage users. I fetch the user data from 'https://jsonplaceholder.typicode.com/users'. I tried to delete data using the fetch DELETE method but it doesn't work. so I made a copy of users and performed the delete operation there.
import { useState } from 'react';
import Table from './components/Table';
function App() {
const [users, setUsers] = useState();
const fetchUserHandler = async () => {
const response = await fetch('https://jsonplaceholder.typicode.com/users');
const data = await response.json();
// Made the copy of the data
let userCopy = JSON.parse(JSON.stringify(data));
setUsers(userCopy);
};
console.log('users in app comp: ', users);
return (
<div className='App'>
<div className='container'>
<div className='fetch-btn'>
<button className='btn' onClick={fetchUserHandler}>
Fetch User
</button>
</div>
<Table users={users} updateState={setUsers} />
</div>
</div>
);
}
export default App;
The DELETE operation is done in TABLE component inside deleteHandler():
export default function Table(props) {
console.log('props.users in table comp: ', props.users);
const deleteHandler = (id) => {
console.log(id);
props.users.splice(
props.users.findIndex((u) => u.id == id),
1,
);
props.updateState(props.users);
};
return (
<div className='users-table'>
<table>
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Email</th>
<th>Phone</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{props.users &&
props.users.map((user, key) => {
return (
<>
<tr key={key}>
<td>{user.id}</td>
<td>{user.name}</td>
<td>{user.email}</td>
<td>{user.phone}</td>
<td>
<button style={{ backgroundColor: 'green' }}>Edit</button>
<button style={{ backgroundColor: 'red' }} onClick={() => deleteHandler(user.id)}>
Delete
</button>
</td>
</tr>
</>
);
})}
</tbody>
</table>
</div>
);
}
the console look like:
Problem:
splice
is in-place modification operation. So it will return you same reference of an array. If you want to update state you have to pass different reference of an array as:
props.updateState([...props.users]);
One more thing, It is not recommended to user index
as a key
so better to use unique id
<tr key={user.id}>
You should add key on the direct element in the callback function, You are adding on tr
not on the <> ... </>
not on Fragment
.
Either you can add key
on React.Fragment
or just remove it. Since you are already adding key
on the tr
.
{props.users &&
props.users.map((user, key) => {
return ( // Removed Fragment
<tr key={user.id}>
<td>{user.id}</td>
Or use as: CODESANDBOX
{props.users &&
props.users.map((user, key) => {
return (
<React.Fragment key={user.id}>
<tr>
<td>{user.id}</td>