useMatch 用于在react-router-dom 中测试多种模式

问题描述 投票:0回答:2

我有以下数组:

const tabsList = [
  { 
    pathPattern: 'users/'
    label: 'Manage users'
  },
  {
    pathPattern: 'users/:id',
    label: 'Edit user profile'
  }
] 

我需要

react-router-dom
中的方法来告诉我上面的哪个数组条目与当前路径名匹配。

基于此,我将能够为组件样式中的活动列表项着色。

我发现方法

useMatch()
看起来几乎可以满足我的要求,但是,它不接受数组,它只接受一种字符串模式用于比较。

// example: current path is /users/82374023854321
const isAllUsersMatch = useMatch('/users') // null
const isUserIdMatch = useMatch('/users/:id') // { ...PathMatch<string> } 

它可以工作,但效果不好,我必须为数组中的每个项目创建一个单独的变量。

react-router-dom
中有类似以下内容吗?

const tabsList = [
  { 
    pathPattern: 'users/'
    label: 'Manage users'
  },
  {
    pathPattern: 'users/:id',
    label: 'Edit user profile'
  }
] 
const activeListItem = tabsList.some((listItem)=> doesItMatch(listItem.pathPattern))

我会使用钩子完成此操作,但在反应中,你不能在回调中使用钩子,因此以下内容将不起作用:

// const activeListItem = tabsList.some((listItem)=> doesItMatch(listItem.pathPattern))
const activeListItem = tabsList.some((listItem)=> useMatch(listItem.pathPattern)) // ERROR
reactjs typescript react-router react-router-dom
2个回答
2
投票

您正在正确的轨道上迭代

tabsList
数组。如果您需要的只是将当前路径与配置对象/数组中的路径相匹配,那么您可以使用
useMatch
 实用程序,而不是使用在嵌套回调函数中不起作用的 
matchPath
钩子
useMatch
钩子直接使用的函数。

import { matchPath, useLocation } from "react-router-dom";

const tabsList = [
  {
    pathPattern: "users/",
    label: "Manage users"
  },
  {
    pathPattern: "users/:id",
    label: "Edit user profile"
  }
];

...

const { pathname } = useLocation();
const activeListItem = tabsList.find(({ pathPattern }) =>
  matchPath(pathPattern, pathname)
);

并将上述内容抽象为自定义钩子:

const useTabsListMatches = (tabsList = []) => {
  const { pathname } = useLocation();
  return tabsList.find(({ pathPattern }) =>
    matchPath(pathPattern, pathname)
  );
}
const activeListItem = useTabsListMatches(tabsList);

1
投票

如果您改变对象的形状,您可能可以使用

react-router
matchRoutes()

const location = useLocation()

const matches = matchRoutes([{ 
  path: 'users/',
  label: 'Manage users',
}, {
  path: 'users/:id',
  label: 'Edit user profile',
}], location)
© www.soinside.com 2019 - 2024. All rights reserved.