URL 由 react-router-dom 'useSearchParams' 设置的更改在由 mui 'Tabs' 组件的 onChange 回调设置时不会保留
URL changes set by react-router-dom 'useSearchParams' are not maintained when set by mui 'Tabs' component's onChange callback
我想根据名为 tab
的搜索参数设置一个选项卡导航组件。
如果我的 url 是 example.com?tab=test2
,我希望我的导航栏显示选中的 test2
项。
我正在为此使用 mui Tabs 组件。
我能够通过获取搜索参数searchParams.get('tab')
成功设置我的Tab
状态,但是,当我设置 tab
属性 时,它只反映了片刻,然后被空状态覆盖(因此 URL 被更改为没有搜索参数)。
我尝试添加一个空检查器来设置默认搜索参数,但它不是“保持”。
非常奇怪的是,如果我简单地使用普通按钮设置搜索参数,更改将“保持”。
我创建了一个 codesandbox minimal implementation 来演示,但是,简而言之,我的更改函数在 mui Tabs
组件的 onChange
回调以及我的简单的按钮 onClick
回调,看起来像这样:
const handleChange = (event: SyntheticEvent, newValue: string) => {
searchParams.set("tab", newValue);
setSearchParams(searchParams);
};
并且该值最初是在组件实例化时设置的(我相信基于控制台日志实验):
const PartsTabNav = () => {
let [searchParams, setSearchParams] = useSearchParams();
let queryTab = searchParams.get("tab");
为什么我的按钮会更改 URL,但不会更改 MUI 选项卡组件的 onChange,即使两者都调用相同的函数?
编辑:根据我的调试,它似乎实际上与 <Link>
组件有关。
完整的示例代码如下:
import { Grid, Tab, Tabs } from "@mui/material";
import { useTheme } from "@mui/material/styles";
import { SyntheticEvent, useEffect } from "react";
import { Link, useSearchParams, Routes, Route } from "react-router-dom";
const tabOptions = [
{
label: "Test1",
route: "test1"
},
{
label: "Test2",
route: "test2"
}
];
const PartsTabNav = () => {
let [searchParams, setSearchParams] = useSearchParams();
let queryTab = searchParams.get("tab");
queryTab = queryTab ? queryTab : "test1";
useEffect(() => {
if (!queryTab) {
searchParams.set("tab", "test1");
setSearchParams(searchParams);
}
}, [searchParams, setSearchParams, queryTab]);
const handleChange = (event: SyntheticEvent, newValue: string) => {
searchParams.set("tab", newValue);
setSearchParams(searchParams);
};
return (
<div>
<Grid container spacing={1}>
<Grid item xs={12}>
<ul>
<li>
<button
onClick={(e) => {
handleChange(e, "test1");
}}
>
one
</button>
</li>
<li>
<button
onClick={(e) => {
handleChange(e, "test2");
}}
>
two
</button>
</li>
</ul>
<Tabs
value={queryTab}
indicatorColor="primary"
textColor="primary"
aria-label="Tabs"
onChange={handleChange}
>
{tabOptions.map((tab, index) => (
<Tab
key={index}
component={Link}
to="#"
label={tab.label}
value={tab.route}
/>
))}
</Tabs>
</Grid>
</Grid>
</div>
);
};
export default function App() {
return (
<div>
<Routes>
<Route path="/" element={<PartsTabNav />} />
</Routes>
</div>
);
}
问题来自使用 Link
(来自 react-router)作为 Tab
的 component
道具。发生了一些导致页面刷新的默认点击处理。更改为以下,解决了问题。
{tabOptions.map((tab, index) => (
<Tab
key={index}
icon={tab.icon}
label={tab.label}
value={tab.route}
/>
))}
我想根据名为 tab
的搜索参数设置一个选项卡导航组件。
如果我的 url 是 example.com?tab=test2
,我希望我的导航栏显示选中的 test2
项。
我正在为此使用 mui Tabs 组件。
我能够通过获取搜索参数searchParams.get('tab')
成功设置我的Tab
状态,但是,当我设置 tab
属性 时,它只反映了片刻,然后被空状态覆盖(因此 URL 被更改为没有搜索参数)。
我尝试添加一个空检查器来设置默认搜索参数,但它不是“保持”。
非常奇怪的是,如果我简单地使用普通按钮设置搜索参数,更改将“保持”。
我创建了一个 codesandbox minimal implementation 来演示,但是,简而言之,我的更改函数在 mui Tabs
组件的 onChange
回调以及我的简单的按钮 onClick
回调,看起来像这样:
const handleChange = (event: SyntheticEvent, newValue: string) => {
searchParams.set("tab", newValue);
setSearchParams(searchParams);
};
并且该值最初是在组件实例化时设置的(我相信基于控制台日志实验):
const PartsTabNav = () => {
let [searchParams, setSearchParams] = useSearchParams();
let queryTab = searchParams.get("tab");
为什么我的按钮会更改 URL,但不会更改 MUI 选项卡组件的 onChange,即使两者都调用相同的函数?
编辑:根据我的调试,它似乎实际上与 <Link>
组件有关。
完整的示例代码如下:
import { Grid, Tab, Tabs } from "@mui/material";
import { useTheme } from "@mui/material/styles";
import { SyntheticEvent, useEffect } from "react";
import { Link, useSearchParams, Routes, Route } from "react-router-dom";
const tabOptions = [
{
label: "Test1",
route: "test1"
},
{
label: "Test2",
route: "test2"
}
];
const PartsTabNav = () => {
let [searchParams, setSearchParams] = useSearchParams();
let queryTab = searchParams.get("tab");
queryTab = queryTab ? queryTab : "test1";
useEffect(() => {
if (!queryTab) {
searchParams.set("tab", "test1");
setSearchParams(searchParams);
}
}, [searchParams, setSearchParams, queryTab]);
const handleChange = (event: SyntheticEvent, newValue: string) => {
searchParams.set("tab", newValue);
setSearchParams(searchParams);
};
return (
<div>
<Grid container spacing={1}>
<Grid item xs={12}>
<ul>
<li>
<button
onClick={(e) => {
handleChange(e, "test1");
}}
>
one
</button>
</li>
<li>
<button
onClick={(e) => {
handleChange(e, "test2");
}}
>
two
</button>
</li>
</ul>
<Tabs
value={queryTab}
indicatorColor="primary"
textColor="primary"
aria-label="Tabs"
onChange={handleChange}
>
{tabOptions.map((tab, index) => (
<Tab
key={index}
component={Link}
to="#"
label={tab.label}
value={tab.route}
/>
))}
</Tabs>
</Grid>
</Grid>
</div>
);
};
export default function App() {
return (
<div>
<Routes>
<Route path="/" element={<PartsTabNav />} />
</Routes>
</div>
);
}
问题来自使用 Link
(来自 react-router)作为 Tab
的 component
道具。发生了一些导致页面刷新的默认点击处理。更改为以下,解决了问题。
{tabOptions.map((tab, index) => (
<Tab
key={index}
icon={tab.icon}
label={tab.label}
value={tab.route}
/>
))}