React Hook报错:Cannot read properties of undefined (reading 'params') 求助
问题排查与解决:React Router v6 下 "Cannot read properties of undefined (reading 'params')" 报错
问题背景
使用React Router v6(教程采用v5),首页正常加载,但产品页触发报错:Cannot read properties of undefined (reading 'params'),推测问题源于路由版本差异。
核心问题分析
1. React Router v6 移除了match props
在v5中组件可通过props获取match对象,但v6完全移除该props,因此ProductScreen组件中解构的{match}为undefined,调用match.params.id必然报错。
2. Redux Action中非法使用React Hook
listProductDetails action内调用了useParams(),但React Hook仅允许在函数组件或自定义Hook的顶层使用,普通函数(如Redux action)中调用Hook违反规则,会触发运行时错误。
解决步骤
1. 修正ProductScreen组件:用useParams获取路由参数
移除match props,改用已导入的useParams Hook获取路由参数:
import React, {useState, useEffect} from 'react' import { Link, useParams } from 'react-router-dom' import { Row, Col, Image, ListGroup, Button, Card } from 'react-bootstrap' import Rating from '../components/Rating' import Loader from '../components/Loader' import Message from '../components/Message' import { useDispatch, useSelector } from 'react-redux' import { listProductDetails } from '../actions/productActions' function ProductScreen() { // 移除{match} props const { id } = useParams(); // 通过useParams获取路由id const dispatch = useDispatch() const productDetails = useSelector(state => state.productDetails) const {loading, error, product} = productDetails useEffect(() =>{ dispatch(listProductDetails(id)) // 传入获取到的id }, [dispatch, id]) // 添加依赖项,避免无效重渲染 // 剩余组件渲染逻辑... }
2. 修正ProductActions.js:移除非法Hook调用
Action应接收组件传入的id参数,同时补全axios导入(原代码缺失):
import axios from 'axios'; // 新增axios导入 export const listProductDetails = (id) => async(dispatch) => { try { dispatch({type: PRODUCT_DETAILS_REQUEST}) // 移除useParams调用,直接使用传入的id const {data} = await axios.get(`/api/products/${id}`) dispatch({ type: PRODUCT_DETAILS_SUCCESS, payload: data }) } catch (error) { dispatch({ type: PRODUCT_DETAILS_FAIL, payload: error.response && error.response.data.message ? error.response.data.message : error.message, }) } }
3. 确认路由配置符合v6语法
确保路由使用v6的element属性而非v5的component:
import { Routes, Route } from 'react-router-dom'; import ProductScreen from './screens/ProductScreen'; function App() { return ( <Routes> {/* 其他路由 */} <Route path="/product/:id" element={<ProductScreen />} /> </Routes> ); }
内容的提问来源于stack exchange,提问作者jpwitt13
相关产品推荐
相关产品推荐

