[英]React-router-dom - No routes matching location '/' when Route has param
[英]How to combine react-router-dom's setSearchParams with route that has a param in a way that allows correct back button usage?
我有一组如下所示的路线:
{
path: '/things',
element: <MainLayout />,
children: [
{
path: 'search',
element: <MainSearch />,
},
{
path: 'search/:thingId',
element: <ThingLayout />,
},
{
path: '',
element: <Navigate to="search" replace />,
},
],
},
其中的想法是您在 MainSearch 上搜索某些内容,得到结果,单击它,然后被带到该事物的页面/things/search/:thingId
。
然而,ThingLayout 也有一个选项卡范式发生,它由搜索参数设置,并且用户单击该组件中的选项卡。
事物布局.tsx
import { useParams, useSearchParams } from 'react-router-dom';
const ThingLayout = () => {
const [searchParams, setSearchParams] = useSearchParams();
const activeTab = searchParams.get('tab');
// When the user first comes here from general search route,
// set the default tab
useEffect(() => {
if (!activeTab) {
setSearchParams({ tab: DEFAULT_TAB });
}
}, []);
// ...
}
我的麻烦是,我需要(我相信)通用的/search/:thingId
路由,以便我所有的各种/search/:thingId?tab=someTab
路由解析到这个组件,然后有代码来检查哪个选项卡是通过searchParams
设置的然后渲染正确的子组件,但如果用户按下后退按钮,URL 将更改为/search/:thingId
然后立即返回/search/:thingId?tab=defaultTab
。 我尝试使用navigate
而不是setSearchParams
来更改 URL:
import { useNavigate } from 'react-router-dom';
// ...
const navigate = useNavigate();
navigate(`?tab=${DEFAULT_INVENTORY_PARTS_TAB}`)
但我遇到了同样的问题:当来自搜索时,首先 URL 将是/search/:thingId
,然后它会变成?tab=defaultTab
。
我已经搜索了反应路由器文档,并查看了很多 stackoverflow 问题,我现在在想也许我只是遵循了一个不好的模式? 我的标签导航方法是否与使用 React Router 的“正确”方式兼容? 如何将一般:id
路线与我操纵的searchParams
路线结合起来?
我的反应路由器版本是"react-router-dom": "^6.2.1"
setSearchParams
的工作方式类似于navigate
function,但仅适用于 URL 查询字符串。 它需要一个选项 object ,它与navigate
的类型参数相同。
declare function useSearchParams( defaultInit?: URLSearchParamsInit ): [URLSearchParams, SetURLSearchParams]; type ParamKeyValuePair = [string, string]; type URLSearchParamsInit = | string | ParamKeyValuePair[] | Record<string, string | string[]> | URLSearchParams; type SetURLSearchParams = ( nextInit?: URLSearchParamsInit, navigateOpts?: : { replace?: boolean; state?: any } ) => void;
传递将导航类型设置为重定向的navigateOpts
object。
import { useParams, useSearchParams } from 'react-router-dom';
const ThingLayout = () => {
const [searchParams, setSearchParams] = useSearchParams();
const activeTab = searchParams.get('tab');
// When the user first comes here from general search route,
// set the default tab
useEffect(() => {
if (!activeTab) {
searchParams.set("tab", DEFAULT_TAB);
setSearchParams(searchParams, { replace: true });
}
}, []);
// ...
}
答案是使用react-router-dom
的useNavigate
钩子提供的navigate
function ,它有一个可以传递给它的replace
参数,来替换历史中的当前项目。
因此,我的代码检查是否选择了一个选项卡,如果没有,则设置搜索参数,现在使用正确的搜索参数集navigate
到 URL,而不是直接且仅设置搜索参数。
import { useParams, useSearchParams } from 'react-router-dom';
const ThingLayout = () => {
const [searchParams, setSearchParams] = useSearchParams();
const activeTab = searchParams.get('tab');
// When the user first comes here from general search route,
// set the default tab
useEffect(() => {
if (!activeTab) {
setSearchParams({ tab: DEFAULT_TAB });
}
}, []);
// ...
}
变成
import { useSearchParams, useNavigate } from 'react-router-dom';
const ThingLayout = () => {
const [searchParams] = useSearchParams();
const navigate = useNavigate();
const activeTab = searchParams.get('tab');
// When the user first comes here from general search route,
// set the default tab
useEffect(() => {
if (!activeTab) {
navigate(`?tab=${DEFAULT_TAB}`, {replace: true});
}
}, []);
// ...
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.