React中点击按钮跳转新页面并传递展示指定数据集对应详情
问题根源
你当前写法无法传值的核心原因有两个:
- React Router 匹配路由渲染页面组件时,默认只会注入路由相关的内置属性,不会自动接收你手动绑定的自定义props,直接在组件参数里解构
ID/ord_no这些字段是拿不到值的。 - 列表里的SELECT按钮仅修改了一个无实际作用的本地状态,既没有触发路由跳转,也没有绑定当前点击行对应的工单数据,自然无法把选中项的信息传到详情页。
修复步骤
1. 先确认路由配置
首先确保你在路由配置文件(通常是App.jsx)中已经注册了详情页的路由:
// 路由配置示例,确保存在这一行 <Route path="/VerifySingleShopOrder" element={<VerifySingleShopOrder />} />
2. 修改列表页 SingleShopOrder.js
用React Router提供的跳转方法,在点击按钮时把当前选中的工单数据随路由一起传到详情页:
- 首先修改路由相关的导入,新增
useNavigate钩子:
// 原导入行替换为 import { Link, useNavigate } from "react-router-dom";
- 在组件内初始化跳转方法,新增选中跳转的处理逻辑:
const SingleShopOrder = () => { // 新增:拿到路由跳转方法 const navigate = useNavigate(); // --- 你原有的state、接口请求代码全部保留 --- const [shopOrder, setshopOrder] = useState([]); useEffect(() => { fetchNormacs(); }, []); const fetchNormacs = () => { axios .get('http://localhost:8090/api/ctms/normacs/machine/NOR1') .then((res) => { setshopOrder(res.data); }) .catch((err) => { console.log(err); }); }; const begin = ()=> { console.log("Clicked") } // 新增:选中工单跳转到详情页的方法 const handleSelectOrder = (currentOrder) => { // 跳转时将当前工单数据存在路由state中传递 navigate('/VerifySingleShopOrder', { state: currentOrder }) } // --- 原有渲染逻辑修改按钮部分 --- if(shopOrder) { return( <> <div className='mainCard'> {/* 左侧导航部分完全保留不用改 */} <div className="container column-left"> <div className="item"> <Link className="navStyle" to="/Overview" onClick={() => begin()}> Overview </Link> </div> <div className="item"> <Link className="navStyle" to="/ShopOrder" onClick={() => begin()}> Shop Order </Link> </div> <div className="item"> <Link className="navStyle" to="/Employee" onClick={() => begin()}> Employee </Link> </div> <div className="item"> <Link className="navStyle" to="/Maintenance" onClick={() => begin()}> Maintenance </Link> </div> </div> <div className='column-right'> <h2 className='so_header'>Select shop order for Normac 1</h2> <div className='wc'> {shopOrder.map((so) => ( <div key={so.ID}> <h3>S/O No :{so.ord_no}</h3> <p>Item No :{so.item_no}</p> <p>Item Desc :{so.item_desc_1}</p> {/* 原按钮替换为下面的写法,点击传入当前循环的so对象 */} <button onClick={() => handleSelectOrder(so)}>SELECT</button> </div> ))} </div> </div> </div> </> ) } return ( <h1>Check the KepServer tags!!!</h1> ) }
注意:你原来给所有按钮加了相同的
id="message"和固定value="1",属于无效写法,多个DOM元素不能共用同一个id,这里直接删掉即可。
3. 修改详情页 VerifySingleShopOrder.js
用useLocation钩子拿到路由传递过来的工单数据即可,不要直接在组件参数里解构字段:
- 首先修改路由相关导入,新增
useLocation钩子:
// 原导入行替换为 import { Link, useLocation } from "react-router-dom";
- 在组件内读取路由传参:
const VerifySingleShopOrder = () => { // 新增:拿到路由携带的state数据 const location = useLocation(); // 解构出需要的工单字段,加空对象兜底避免刷新时报错 const { ID, ord_no, item_no, item_desc_1 } = location.state || {}; // --- 你原有的其他逻辑保留 --- const [message, setMessage] = useState(''); // 原来初始值是空数组,改成空字符串更合理 const handleChange = event => { setMessage(event.target.value); } const begin = ()=> { console.log("Clicked") } // 渲染部分完全不用改,原来的{ord_no}等变量已经可以正常拿到值 return( <> <div className='mainCard'> <div className="container column-left"> <div className="item"> <Link className="navStyle" to="/Overview" onClick={() => begin()}> Overview </Link> </div> <div className="item"> <Link className="navStyle" to="/ShopOrder" onClick={() => begin()}> Shop Order </Link> </div> <div className="item"> <Link className="navStyle" to="/Employee" onClick={() => begin()}> Employee </Link> </div> <div className="item"> <Link className="navStyle" to="/Maintenance" onClick={() => begin()}> Maintenance </Link> </div> </div> <div className='column-right'> <h2 className='so_header'>Verify shop order for Normac 1</h2> <div className='wc'> <h3>S/O No :{ord_no}</h3> <p>Item No :{item_no}</p> <p>Item Desc :{item_desc_1}</p> <button onClick={handleChange}>LOGIN & VERIFY</button> </div> </div> </div> </> ) } export default VerifySingleShopOrder;
补充优化建议
- 上面用路由state传值的方式,用户手动刷新详情页时state会丢失,如果要避免这个问题,可以改用动态路由传参:把路由配置改成
/VerifySingleShopOrder/:orderId,跳转时拼接工单ID到路径上,详情页拿到ID后再调用接口查询对应工单的完整详情,这种方式刷新页面也不会丢数据,是生产环境更常用的方案。 - 没有用到的状态和逻辑及时删掉,避免代码冗余。
内容的提问来源于stack exchange,提问作者Glenn94
相关产品推荐
相关产品推荐

