React JS中CRUD操作后如何重新渲染/更新表格?
Hey there, let's dig into why your table isn't updating after edits or deletes. Looking at your code, there are a few key issues preventing React from re-rendering the table properly. Here's how to fix them step by step:
1. Replace index with a unique identifier as the row key
Using index as the key for table rows is a common pitfall. When you add or remove items, indices shift, and React might not recognize that rows have changed. Instead, use the unique officeId from your data:
<tr key={list.officeId}> {/* Replace index with list.officeId */} <td><img style={{height: '30px', width: '30px'}} src={list.imageData} alt="icon"/></td> <td>{list.name}</td> <td>{list.address}</td> <td><button type="button" onClick={(e) => this.handleEdit(list.officeId)}><i className="fa fa-pencil" aria-hidden="true"></i></button></td> <td><button type="button" onClick={(e) => this.handleDelete(list.officeId)}><i className="fa fa-trash" aria-hidden="true"></i></button></td> </tr>
2. Fix the handleEdit logic
Right now, you're calling setState inside a map loop, which triggers multiple unnecessary state updates. Instead, find the matching row first and update state once:
handleEdit(id) { // Find the specific row instead of looping through all const selectedRow = this.state.data.find(row => row.officeId === id); if (selectedRow) { this.setState({ displayData: selectedRow }); } this.displayOfficeList(); }
3. Wait for async delete actions to complete before fetching data
In handleDelete, you dispatch a delete action and immediately call displayOfficeList. If deleteOffice is an asynchronous action (like making an API call), the fetch might run before the delete finishes, leaving you with stale data.
Assuming your deleteOffice action returns a promise, await it first:
async handleDelete(id) { const { dispatch } = this.props; // Wait for the delete operation to finish await dispatch(commonActions.deleteOffice(id)); this.displayOfficeList(); }
If your action doesn't return a promise, adjust your Redux middleware (like using Thunk) to make it async, or add a callback in the action creator to trigger the fetch after completion.
4. Simplify state updates in displayOfficeList
You're calling setState twice here, which is redundant. Combine both state updates into one call, and check if toggleFlag() is interfering with your state flow:
displayOfficeList() { // Remove toggleFlag if it's not needed, or adjust it to work with combined state updates commonServices.getOfficeList().then((res) => { this.setState({ data: res.content, dataUpdated: true // Update both properties in a single setState call }); }); }
You can also simplify the tbody rendering—relying on dataUpdated is unnecessary if you're updating data correctly. Just render directly from this.state.data:
<tbody> {this.state.data.map((list) => ( <tr key={list.officeId}> {/* Row content */} </tr> ))} </tbody>
React will automatically re-render the list when data changes.
5. Ensure state updates are immutable
Whenever you modify this.state.data elsewhere, create a new array instead of mutating the existing one. For example, adding an item should look like:
this.setState(prevState => ({ data: [...prevState.data, newItem] }));
Directly mutating state won't trigger a re-render.
Putting all these changes together should resolve the issue where your table doesn't update after edits or deletes.
内容的提问来源于stack exchange,提问作者Miral Kumbhani

