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:
- the State is updating in App component but the Table componet is not re-rendering.
- I want to update my table after delete operation.
- I am assigning key prop to every row, why it is showing warning?
2
Answers
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:CODESANDBOX
One more thing, It is not recommended to user
index
as akey
so better to useunique id
You should add key on the direct element in the callback function, You are adding on
tr
not on the<> ... </>
not onFragment
.Either you can add
key
onReact.Fragment
or just remove it. Since you are already addingkey
on thetr
.Or use as:
CODESANDBOX
I think you should use the updateState with filtering the oldState like this: