React CURD应用编辑时useParams控制台输出0但URL中id正确的问题
问题根因
- 路由上下文被阻断:你使用redux的
connect高阶组件包裹了业务组件,在React Router v6版本中,HOC会阻断路由上下文的向下传递,导致useParams无法读取到最新的路由参数,初始值为undefined转数字后就会变成0。 - 路由配置不匹配:如果路由路径的参数占位符名称不是
id,比如你写的是/edit/:userId,那么useParams().id就会返回undefined,转换为数字后值为0。 - useEffect依赖缺失:你当前的useEffect没有添加任何依赖项,会在每次组件渲染时重复执行,且始终读取初始渲染时的id值,不会随路由变化更新。
修复方案
- 优先改用redux钩子
useSelector、useDispatch替代connect,避免HOC阻断路由上下文的问题 - 校验路由配置,确保路径参数占位符和解构的变量名一致,示例路由配置:
<Route path="/edit/:id" element={<About />} /> - 给useEffect添加正确的依赖项,仅当关联变量变化时才执行逻辑
- 增加id的兜底校验,避免undefined转数字为0的异常
如果需要保留connect的用法,可以自定义withRouter高阶组件注入路由上下文:
// 自定义withRouter,兼容react-router v6 import { useParams, useLocation, useNavigate } from 'react-router-dom'; const withRouter = (Component) => { const Wrapper = (props) => { const location = useLocation(); const navigate = useNavigate(); const params = useParams(); return <Component {...props} router={{ location, navigate, params }} />; }; return Wrapper; }; // 导出组件时先套withRouter再套connect export default connect(mapStateToProps, { getItemById })(withRouter(About));
修复后完整代码
import React, { useState, useEffect } from 'react'; import { useSelector, useDispatch } from 'react-redux'; import { useParams } from 'react-router'; import { getItemById } from '../actions'; const About = () => { const [text, setText] = useState('') const { id } = useParams(); const dispatch = useDispatch(); const toEdit = useSelector(state => state.items); // 兜底校验,id不存在时可自定义跳转逻辑 const userId = id ? parseInt(id) : null; console.log('id from url ' + userId); useEffect(() => { // 没有合法id时不执行查询逻辑 if (!userId) return; console.log(toEdit); const findById = toEdit.find((element) => element.id === userId); console.log(findById); const user = toEdit.find((element) => { console.log(element.id + " " + userId + " url id" ); return element.id === userId; }) // 找到条目后初始化输入框内容 if (user) setText(user.text); // 调用获取详情的action dispatch(getItemById(userId)); // 添加依赖项,仅当id、列表数据、dispatch变化时执行 }, [userId, toEdit, dispatch]) const handleChange = (e) => { setText(e.target.value) } return ( <div> <input value={text} onChange={handleChange} /> </div> ) }; export default About;
内容的提问来源于stack exchange,提问作者Abhishek kumar
相关产品推荐
相关产品推荐

