You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

react-router-dom@6中mapStateToProps读取params报错及适配问题

React Router v6 适配 Redux 代码:解决 match.params 未定义与 useParams 使用错误

问题背景

升级到react-router-dom@6后出现以下错误:

Cannot read properties of undefined (reading 'params') TypeError: Cannot read properties of undefined (reading 'params') at Function.mapStateToProps [as mapToProps]

尝试改用useParams时触发Hook规则错误:

React Hook useParams is called in function mapStateToProps that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word "use" react-hooks/rules-of-hooks

现有核心代码如下:

组件内部逻辑

const [product, setProduct] = useState({ ...props.product });
useEffect(() => {
  if (categories.length === 0) {
    getCategories()
  }
  setProduct({ ...props.product });
  // eslint-disable-next-line react-hooks/exhaustive-deps
}, [props.product]);

Redux mapStateToProps

export function getProductById(products, productId) {
  let product = products.find(product => product.id === productId) || null;
  return product;
}

function mapStateToProps(state, ownProps) {
  const productId = ownProps.match.params.productId;
  const product = productId && state.productListReducer.length > 0
    ? getProductById(state.productListReducer, productId)
    : {}
  return {
    product: product,
    products: state.productListReducer,
    categories: state.categoryListReducer
  }
}

路由配置

<Routes>
  <Route path="/" element={<DashBoard></DashBoard>}></Route>
  <Route path="/cart" element={<CartDetails></CartDetails>}></Route>
  <Route
    path="/saveproduct/:productId"
    element={<AddOrUpdateProduct></AddOrUpdateProduct>}>
  </Route>
</Routes>

解决方案

React Router v6不再向组件传递match、history等props,且Hooks只能在组件/自定义Hook中调用,因此需要重构代码:

1. 组件内直接获取路由参数与Redux状态

移除mapStateToProps,改用useParams(获取路由参数)和useSelector(获取Redux状态),代码如下:

import { useParams, useNavigate } from 'react-router-dom';
import { useSelector, useDispatch } from 'react-redux';
import { useState, useEffect } from 'react';
import { getCategories } from './your-action-path'; // 替换为实际action文件路径
import { getProductById } from './your-utils-path'; // 替换为实际工具函数路径

function AddOrUpdateProduct() {
  // 获取路由参数
  const { productId } = useParams();
  // 获取Redux状态
  const products = useSelector(state => state.productListReducer);
  const categories = useSelector(state => state.categoryListReducer);
  // 获取dispatch方法
  const dispatch = useDispatch();
  // 替代history的导航方法
  const navigate = useNavigate();

  // 计算当前需要的product
  const currentProduct = productId && products.length > 0 
    ? getProductById(products, productId) 
    : {};

  const [localProduct, setLocalProduct] = useState({ ...currentProduct });

  useEffect(() => {
    if (categories.length === 0) {
      dispatch(getCategories());
    }
    setLocalProduct({ ...currentProduct });
  }, [currentProduct, categories, dispatch]);

  // 示例:替代原history.push逻辑
  const handleNavigate = () => {
    navigate('/cart');
  };

  // 组件其他业务逻辑...

  return (
    // 组件JSX结构...
  );
}

export default AddOrUpdateProduct;

2. 移除connect包裹

如果之前用connect(mapStateToProps)(AddOrUpdateProduct)导出组件,现在直接导出组件即可,无需connect包裹。

关键说明

  • React Router v6取消了props传递match/history的机制,必须通过useParams/useNavigate等Hooks获取路由相关能力
  • useParams是React Hook,只能在React组件(首字母大写)或自定义Hook(以use开头)中调用,不能在mapStateToProps这类普通函数中使用
  • useSelector可以直接替代mapStateToProps的作用,灵活获取Redux状态中的数据

内容的提问来源于stack exchange,提问作者Emir Burak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 12:20:37