React 中获取当前路由信息

在 React 中获取当前路由信息,根据使用的路由库不同(如 React Router v5/v6 或 Next.js),方法也有所区别。以下是常见场景的解决方案:


1. 使用 React Router v6

获取当前路径(pathname)、查询参数(search)等
jsx 复制代码
import { useLocation, useParams, useSearchParams } from 'react-router-dom';

function MyComponent() {
  // 获取路径信息(如 /users/123?name=foo)
  const location = useLocation();
  console.log(location.pathname); // "/users/123"
  console.log(location.search);   // "?name=foo"

  // 获取动态路由参数(如 /users/:id)
  const params = useParams();
  console.log(params.id); // "123"

  // 获取查询参数(URLSearchParams 对象)
  const [searchParams] = useSearchParams();
  console.log(searchParams.get('name')); // "foo"

  return <div>Current Path: {location.pathname}</div>;
}
获取路由匹配信息
jsx 复制代码
import { useMatch } from 'react-router-dom';

// 检查当前路由是否匹配某个路径
const match = useMatch('/users/:id');
if (match) {
  console.log(match.params.id); // 动态参数
}

2. 使用 React Router v5

获取路由信息
jsx 复制代码
import { useLocation, useParams, useRouteMatch } from 'react-router-dom';

function MyComponent() {
  const location = useLocation();
  const params = useParams();
  const match = useRouteMatch();

  console.log(location.pathname); // 当前路径
  console.log(params);            // 动态参数
  console.log(match.url);         // 匹配的URL

  return <div>Current Route: {location.pathname}</div>;
}
类组件中获取路由
jsx 复制代码
import { withRouter } from 'react-router-dom';

class MyComponent extends React.Component {
  render() {
    const { location, match, params } = this.props;
    return <div>Path: {location.pathname}</div>;
  }
}

export default withRouter(MyComponent);

3. 在 Next.js 中获取路由

Pages Router(传统方式)
jsx 复制代码
import { useRouter } from 'next/router';

function MyComponent() {
  const router = useRouter();
  
  // 获取完整路由信息
  console.log(router.pathname); // "/posts/[id]"
  console.log(router.query);    // { id: "123" }(动态参数 + 查询参数)
  console.log(router.asPath);   // "/posts/123?name=foo"(浏览器显示的实际路径)

  return <div>Current Page: {router.pathname}</div>;
}
App Router(Next.js 13.4+)
jsx 复制代码
// 在 Server Component 中
import { usePathname, useSearchParams } from 'next/navigation';

export default function Page() {
  const pathname = usePathname();       // "/dashboard"
  const searchParams = useSearchParams(); // URLSearchParams 对象

  return <div>Path: {pathname}</div>;
}

4. 获取当前路由的额外场景

获取路由的 basename
jsx 复制代码
// React Router v6
import { useMatches } from 'react-router-dom';
const matches = useMatches();
console.log(matches[0].pathname); // 包含 basename 的完整路径

// Next.js (需手动处理)
const basePath = process.env.NEXT_PUBLIC_BASE_PATH || '';
监听路由变化
jsx 复制代码
// React Router
useEffect(() => {
  const unlisten = history.listen((update) => {
    console.log('Route changed to:', update.location.pathname);
  });
  return unlisten; // 清理监听
}, []);

// Next.js
useEffect(() => {
  router.events.on('routeChangeComplete', (url) => {
    console.log('Route changed to:', url);
  });
}, [router]);

5. 常见问题解决

问题:路由信息未更新
  • 原因:组件未被路由上下文包裹。

  • 解决 :确保组件在 <BrowserRouter><Router> 内部:

    jsx 复制代码
    // 根组件中
    import { BrowserRouter } from 'react-router-dom';
    ReactDOM.render(
      <BrowserRouter>
        <App />
      </BrowserRouter>,
      document.getElementById('root')
    );
问题:Next.js 中 router.query 初始为空
  • 原因:静态优化导致首次渲染时无参数。

  • 解决 :添加加载状态判断:

    jsx 复制代码
    if (!router.isReady) return <div>Loading...</div>;

总结:按需选择方法

场景 推荐 API 示例
React Router v6 useLocation, useParams const { pathname } = useLocation()
React Router v5 withRouter, useRouteMatch export default withRouter(MyComponent)
Next.js Pages next/router const router = useRouter()
Next.js App Router next/navigation const pathname = usePathname()
获取查询参数 useSearchParams (React Router) const [params] = useSearchParams()
监听路由变化 history.listen 或 Next.js 事件 router.events.on('routeChangeComplete', ...)

根据你的路由库选择对应方法即可准确获取当前路由信息!