React-Redux中表格按钮跳转动态路由传递志愿者数据的实现问题
1. 外部列配置中的动态路由跳转修复
你当前列配置里的formatter存在两个核心错误:
- 没有正确接收formatter的回调参数:React Table类组件库的formatter签名为
(当前单元格值, 整行数据对象, 行索引),你之前写的(rowContent, row)参数顺序混乱,且没有从行对象中取真实的志愿者ID,反而引用了未定义的全局_id变量,导致跳转路径永远是/volenteerRoute/undefined - 误认为动态路由需要在列配置里绑定组件状态:实际上
<Link>组件本身只需要正确拼接路径字符串,完全可以作为静态常量导出,不需要把列配置移回组件内部。
修正后的操作列配置代码:
{ dataField: "_id", text: "פעולות", // 正确接收参数:第一个是当前单元格的值(也就是_id),第二个是整行的志愿者数据 formatter: (cellValue, row) => { return ( <Link to={`/volenteerRoute/${row._id}`}> <button className='btn btn-outline-primary btn lg'>view</button> </Link> ) } }
额外提醒:你的现有列配置存在两个隐性问题:1. 字段绑定错误:“שם פרטי”“שם משפחה”两个列都绑定了name字段,“עיר”“מספר טלפון”两个列都绑定了phone字段,需要对应调整为接口返回的真实字段名(比如firstName/lastName/city),避免页面渲染重复内容;2. 拼写不统一:组件、路由路径、action中把正确的Volunteer拼成了Volenteer,建议统一修正,避免路由匹配失败。
2. 单条志愿者数据的Redux请求改造
选型结论
不要使用Link的state传详情数据:用户直接访问详情URL、刷新页面时,Link携带的内存态state会完全丢失,必须通过路由参数拿ID、独立请求接口的方案实现数据获取。
Action层修正
你当前的单条请求action硬编码了:id字符串,没有参数入口,无法拼接真实请求地址,修正为:
// 现有全量列表请求保持不变 export const requestVolunteerData = () => getData('http://localhost:8000/api/volunteer'); // 改造:接收ID参数,拼接真实请求地址 export const requestOneVolunteerData = (volunteerId) => getData(`http://localhost:8000/api/volunteer/${volunteerId}`);
注:不需要在点击view按钮时把ID手动传给action,路由本身的路径参数已经携带了ID信息,详情组件挂载时可以直接从路由中读取ID发起请求,减少视图层的冗余传值逻辑。
3. 详情组件的正确实现
你当前组件的写法存在基础错误:React-Router注入的路由props是顶级属性,不存在嵌套的props字段,导致你根本拿不到路由参数、Redux注入的state和action方法。
完整可运行的详情组件代码(以函数组件+Hooks为例,最小改动适配现有逻辑):
import React, { useEffect } from 'react'; import { connect } from 'react-redux'; import { requestOneVolunteerData } from '../actions'; import Loading from '../components/Loading/Loading'; // 从Redux store映射需要的状态 const mapStateToProps = state => ({ currentVolunteer: state.requestEntitiesReducer.entities, isPending: state.requestEntitiesReducer.isPending }) // 绑定action到dispatch const mapDispatchToProps = dispatch => ({ onRequestSingleVolunteer: (volunteerId) => dispatch(requestOneVolunteerData(volunteerId)) }) const VolenteerDetails = (props) => { // 从顶级props解构需要的内容(包含路由注入的match参数) const { match, currentVolunteer, isPending, onRequestSingleVolunteer } = props; // 组件挂载时,从路由参数中取ID,发起单条数据请求 useEffect(() => { onRequestSingleVolunteer(match.params.id) }, [match.params.id, onRequestSingleVolunteer]) // 加载中展示状态 if (isPending) return <Loading /> return ( <div className='tc'> <h2>volenteer details </h2> {/* 拿到currentVolunteer后渲染对应字段即可 */} <p>name: {currentVolunteer?.name}</p> <p>phone: {currentVolunteer?.phone}</p> </div> ) } export default connect(mapStateToProps, mapDispatchToProps)(VolenteerDetails);
额外适配说明:如果使用React Router v6,获取路由参数不需要从props里解构match,直接引入useParamsHook即可简化代码:
import { useParams } from 'react-router-dom'; // 在组件内部直接取路由参数中的ID const { id } = useParams();
内容的提问来源于stack exchange,提问作者Nathan Barel

