React动态表格渲染key属性添加位置及编辑异常修复
问题修复方案
你的代码存在3个核心问题,分别导致key属性警告、编辑功能失效、空输入时表格不显示,逐一修复即可:
- key警告原因:
map遍历生成的直接子元素是<Fragment>,你之前把key绑定在Fragment内部的EditableRow/ReadOnlyRow组件上,React无法识别列表项的唯一标识;且List.js中未导入Fragment,本身会触发语法错误。 - 编辑失效原因:你将编辑后的数据保存在
contactsstate中,但过滤逻辑始终使用导入的原始静态data做筛选渲染,state更新后页面不会读取修改后的值,编辑操作无法生效。 - 空输入不显示内容原因:搜索词为空时过滤逻辑返回空字符串(falsy值),所有数据都会被过滤,表格无内容。
修复步骤
1. 修复App.js
补上缺失的useState导入,修复后完整代码:
import { useState } from "react"; import TextField from "@mui/material/TextField"; import List from "./Components/List"; import "./App.css"; function App() { const [inputText, setInputText] = useState(""); let inputHandler = (e) => { // 输入内容转小写 var lowerCase = e.target.value.toLowerCase(); setInputText(lowerCase); }; return ( <div className="main"> <h1>Search</h1> <div className="search"> <TextField id="outlined-basic" onChange={inputHandler} variant="outlined" fullWidth label="Search" /> </div> <List input={inputText} /> </div> ); } export default App;
2. 修复List.js
- 补上
Fragment、useState的导入 - 将key绑定到map返回的最外层Fragment上
- 过滤逻辑改用
contactsstate作为数据源,替换原始静态data - 修正空搜索词的过滤逻辑,无输入时返回全部数据
修复后完整代码:
import { useState, Fragment } from "react"; import data from "./ListData.json" import ReadOnlyRow from "./ReadOnlyRow.js" import EditableRow from "./EditableRow.js" function List(props) { const [contacts, setContacts]=useState(data); const [editContactId, setEditContactId] = useState(null); const [editFormData, setEditFormData] = useState({ CustomerLogonId: "", FirstName: "", LastName: "", Address: "", City: "", Zip: "", }); const handleFormChange = (event) => { const fieldName = event.target.getAttribute("name"); const fieldValue = event.target.value; const newFormData = {...editFormData}; newFormData[fieldName] = fieldValue; setEditFormData(newFormData); }; const handleFormSubmit = (event) => { event.preventDefault(); const editedContact = { id : editContactId, CustomerLogonId: editFormData.CustomerLogonId, FirstName: editFormData.FirstName, LastName: editFormData.LastName, Address: editFormData.Address, City: editFormData.City, Zip: editFormData.Zip } const newContacts = [...contacts]; const index = contacts.findIndex((item) => item.id === editContactId) newContacts[index] = editedContact; setContacts(newContacts); setEditContactId(null); } const handleEditClick = (event, item) => { event.preventDefault(); setEditContactId(item.id); const formValues = { CustomerLogonId: item.CustomerLogonId, FirstName: item.FirstName, LastName: item.LastName, Address: item.Address, City: item.City, Zip: item.Zip } setEditFormData(formValues); } const handleCancelClick = () => { setEditContactId(null); }; // 改用contacts state作为过滤数据源,修正空输入逻辑 const filteredData = contacts.filter((el) => { // 无输入时返回所有数据 if (props.input === '') { return true; } // 匹配输入的邮箱字段 else { return el.CustomerLogonId.toLowerCase().includes(props.input) } }) return ( <div className='app-container'> <form onSubmit={handleFormSubmit}> <table> <thead> <tr> <th>CustomerLogonId</th> <th>FirstName</th> <th>LastName</th> <th>Address</th> <th>City</th> <th>Zip</th> <th>Actions</th> </tr> </thead> <tbody> {filteredData.map((item) => ( // key绑定到map遍历的最外层直接子元素上 <Fragment key={item.id}> {editContactId === item.id ? ( <EditableRow editFormData={editFormData} handleFormChange={handleFormChange} handleCancelClick={handleCancelClick} /> ) : ( <ReadOnlyRow item = {item} handleEditClick = {handleEditClick} /> ) } </Fragment> ))} </tbody> </table> </form> </div> ) } export default List
3. ReadOnlyRow.js、EditableRow.js、ListData.json
这三个文件逻辑无问题,不需要修改。
修复后控制台key警告会消失,点击Edit按钮可以正常进入编辑状态,修改后点Save即可保存更新内容,搜索框无输入时会显示全部客户数据,输入关键词时实时过滤匹配结果。
内容的提问来源于stack exchange,提问作者user19441830
相关产品推荐
相关产品推荐

