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)作为 Tabcomponent 道具。发生了一些导致页面刷新的默认点击处理。更改为以下,解决了问题。

{tabOptions.map((tab, index) => (
    <Tab
        key={index}
        icon={tab.icon}
        label={tab.label}
        value={tab.route}
    />
))}