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

react-router中withRouter有何替代方案?子组件如何获取match属性

React Router v6 中withRouter的替代方案

React Router 从v6版本开始正式移除了withRouter高阶组件,无需降级版本、无需逐层透传props,使用官方提供的路由Hooks即可实现完全一致的能力。

核心API对应关系

原有withRouter会向组件注入match/location/history三个路由相关属性,v6中对应Hook如下:

  • 路由跳转能力(原history.push/history.replace):使用useNavigate()Hook
  • 当前路径信息、匹配参数(原match.url/match.params):使用useResolvedPath()、useMatch()、useParams()Hook
  • 当前路由位置对象(原location):使用useLocation()Hook

注意:禁止直接操作window.history实现跳转,React Router内部维护了独立的路由上下文状态,直接修改原生history对象会导致路由状态不同步、嵌套路由匹配失效、导航守卫不触发等异常,所有跳转逻辑请使用官方提供的导航API。

原组件改造示例(函数组件)

针对提供的MenuItem组件,改造后代码如下,完全保留原有交互逻辑:

import React from "react";
import './menuItem.style.scss'
import { useNavigate, useResolvedPath } from "react-router";

const MenuItem = ({title, imageUrl,size,linkUrl}) => {
    const navigate = useNavigate();
    // 解析当前路由下拼接linkUrl的目标路径,替代原match.url拼接逻辑
    const targetPath = useResolvedPath(linkUrl);

    return (
        <div 
            className={`${size} menu-item`} 
            onClick={() => navigate(targetPath.pathname)}
        >
            <div style={{backgroundImage: `url(${imageUrl})`}}  className="background-image" ></div>
            <div className="content">
                <h1 className="title">{title.toUpperCase()}</h1>
                <span className="subtitle">Shop Now</span>
            </div>
        </div>
    )
};
export default MenuItem;

类组件兼容方案

如果你使用的是类组件无法直接使用Hook,可以自行封装和旧版API完全一致的withRouter高阶组件,无需修改原有业务代码:

import { useNavigate, useLocation, useParams } from 'react-router';

export const withRouter = (WrappedComponent) => {
  function WithRouterWrapper(props) {
    const navigate = useNavigate();
    const location = useLocation();
    const params = useParams();

    // 组装和旧版withRouter一致的props结构
    const routerProps = {
      match: {
        url: location.pathname,
        params: params
      },
      location,
      history: {
        push: navigate,
        replace: (path) => navigate(path, {replace: true})
      }
    };

    return <WrappedComponent {...routerProps} {...props} />;
  }
  return WithRouterWrapper;
};

封装完成后,原有组件的export default withRouter(MenuItem)写法可以直接保留,不需要做其他修改。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 01:51:20