React加载新增/更新员工组件时隐藏原有数据表格的实现问题
问题修复方案
核心问题说明
- 存在多个独立的Router实例,路由规则不互通
- Update组件的路由规则写在表格行循环内,路径匹配时所有行都会渲染更新表单
- 没有对表格做路由条件渲染控制,导致所有路径下表格始终可见
具体修改步骤
1. 重构App.js,统一管理路由
把所有路由规则移到最外层,避免多Router实例冲突,只有根路径渲染表格,其他路径渲染对应表单:
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; import Table from './Table'; import AddNew from './AddNew'; import UpdateMember from './UpdateMember'; function App() { return ( <Router> <Routes> <Route path="/" element={<Table />} /> <Route path="/AddNew" element={<AddNew />} /> <Route path="/UpdateMember/:id" element={<UpdateMember />} /> </Routes> </Router> ); } export default App;
2. 重构Table.js,移除内部路由逻辑
删除组件内的Router、Route相关代码,只保留跳转链接,更新按钮链接携带员工id参数:
import { Link } from 'react-router-dom'; import { useState, useEffect } from 'react'; function Table() { const [list, setList] = useState([]); useEffect(() => { let mounted = true; getList().then((items) => { if (mounted) { setList(items); } }); return () => (mounted = false); }, []); const DeleteRow = (id) => (event) => { let header = new Headers(); header.append("Content-Type", "application/json"); header.append("Accept", "application/json"); return fetch(DeleteUrl + id, { method: "DELETE", headers: header }).then( () => { fetch(BaseUrl, { method: "GET", headers: header }) .then((response) => response.json()) .then((result) => { setList(result); }); } ); }; return ( <div> <h1>Employees Data</h1> <Link to="/Addnew"> <button style={{ float: "right" }} className="button btn-primary LinkButton" > Add New </button> </Link> <table> <thead> <tr> <th>ID</th> <th>Name</th> <th>Department</th> <th>Salary</th> <th>Actions</th> <th>Actions</th> </tr> </thead> <tbody> {list.map((item) => ( <tr key={item.id}> <td><center>{item.id}</center></td> <td><center>{item.name}</center></td> <td><center>{item.department}</center></td> <td><center>{item.salary}</center></td> <td> <center> <button className="button btn-danger" onClick={DeleteRow(item.id)} > Delete </button> </center> </td> <td> <center> <Link to={`/UpdateMember/${item.id}`}> <button className="button btn-warning LinkButton"> Update </button> </Link> </center> </td> </tr> ))} </tbody> </table> </div> ); } export default Table;
3. 修改AddNew.js,提交成功后跳回首页
新增提交成功后自动跳转回表格页,删除冗余的list状态:
import { useState } from 'react'; import { useNavigate } from 'react-router-dom'; function AddNew() { const [Name, setName] = useState(""); const [Department, setDepartment] = useState(""); const [Salary, setSalary] = useState(""); const navigate = useNavigate(); const PostData = (event) => { event.preventDefault(); const Data = { name: Name, department: Department, salary: Salary, }; let header = new Headers(); header.append("Content-Type", "application/json"); fetch(PostUrl, { method: "POST", headers: header, body: JSON.stringify(Data), }) .then(() => { // 提交成功跳回首页显示表格 navigate('/'); }); }; return ( <div> <form onSubmit={PostData}> <h2>Add New Members</h2> <span>* All fields are required</span> <div className="outerDiv"> <div className="innerDiv"> <input type="text" autoComplete="off" name="name" placeholder="Name" onChange={(event) => setName(event.target.value)} /> </div> <div className="innerDiv"> <input type="text" autoComplete="off" name="Department" placeholder="Department" onChange={(event) => setDepartment(event.target.value)} /> </div> <div className="innerDiv"> <input type="text" autoComplete="off" name="Salary" placeholder="Salary" onChange={(event) => setSalary(event.target.value)} /> </div> <input className="btn btn-primary" type="submit" value="Save" /> </div> </form> </div> ); } export default AddNew;
4. 修改UpdateMember.js,获取路由参数、提交后跳转
从路由参数拿到要更新的员工id,提交成功后跳回首页:
import { useState } from 'react'; import { useParams, useNavigate } from 'react-router-dom'; function UpdateMember() { const { id } = useParams(); const navigate = useNavigate(); const [Name, setName] = useState(""); const [Department, setDepartment] = useState(""); const [Salary, setSalary] = useState(""); const UpdateRow = (event) => { event.preventDefault(); const PutData = { name: Name, department: Department, salary: Salary, }; let header = new Headers(); header.append("Content-Type", "application/json"); header.append("Accept", "application/json"); fetch(`${PutUrl}${id}`, { method: "PUT", headers: header, body: JSON.stringify(PutData), }) .then((response) => response.json()) .then(() => { // 更新成功跳回首页 navigate('/'); }); }; return ( <div> <form onSubmit={UpdateRow}> <span className="text">* All fields are required</span> <hr /> <div> <h2>Update Information</h2> <div className="outerDiv"> <div className="innerDiv"> <input type="text" autoComplete="off" name="name" placeholder="Name" onChange={(event) => setName(event.target.value)} /> </div> <div className="innerDiv"> <input type="text" autoComplete="off" name="Department" placeholder="Department" onChange={(event) => setDepartment(event.target.value)} /> </div> <div className="innerDiv"> <input type="text" autoComplete="off" name="Salary" placeholder="Salary" onChange={(event) => setSalary(event.target.value)} /> </div> <button style={{ float: "right" }} className="button btn-warning" type="submit" > Update </button> </div> </div> </form> </div> ); } export default UpdateMember;
修复后效果
- 点击Add New/Update按钮时,自动跳转到对应表单页,表格自动隐藏
- 提交新增/更新请求成功后,自动跳回首页显示最新的员工表格
- 不会再出现每行都渲染更新表单的问题
内容的提问来源于stack exchange,提问作者Abdul Muhamin Rehman
相关产品推荐
相关产品推荐

