【问题标题】:Material-ui: Routing tab using sharp(#) not slash(/)Material-ui:使用尖锐(#)而不是斜杠(/)的路由选项卡
【发布时间】:2021-09-10 08:42:44
【问题描述】:

我对 React 很陌生,我现在正在使用 ReactJS 和 material-ui 框架开发一个网站。

我的问题是如何自定义标签链接网址,如this site

在此站点上,当我切换选项卡按钮时,通过添加 #(a-custom-tab-link) 来更改 URL。 假设我在xxx/yyy url 上,如果我切换名称为zzz 的选项卡,则url 将更改为xxx/yyy#zzz

我已经使用引用 material-ui tabs docs 的 material-ui 选项卡组件制作了选项卡。 我可以使用useRouteMatch 更改标签网址,代码示例是here

这是我的问题。

  1. 如何更改标签 URL 不是通过添加 / 而是添加 #tab on this site
  2. 如何将第一个选项卡的路由器设置为与其父级路由器相同,以便自动显示。 (我在没有考虑路由器的情况下这样做,但如果我考虑在选项卡切换上更改路由器,我不能这样做)

这是我现在的代码 sn-p。

  var TabHeaders = tabs.map((tab, index) => (
    <Tab
      key={index.toString()}
      component={Link}
      to={`${match.url}/${tab.label}`}
      label={tab["label"]}
      {...a11yProps(tab["index"])}
    />
  ));

  var TabContents = tabs.map((tab, index) => (
    <Route key={tab.id} exact path={`${match.url}/${tab.label}`}>
      <TabPanel value={value} index={tab["index"]}>
        {tab["children"]}
      </TabPanel>
    </Route>
  ));

简单地将 / 更改为 # 并不能像下面这样工作。

  var TabHeaders = tabs.map((tab, index) => (
    <Tab
      key={index.toString()}
      component={Link}
      to={`${match.url}#${tab.label}`}
      label={tab["label"]}
      {...a11yProps(tab["index"])}
    />
  ));

  var TabContents = tabs.map((tab, index) => (
    <Route key={tab.id} exact path={`${match.url}#${tab.label}`}>
      <TabPanel value={value} index={tab["index"]}>
        {tab["children"]}
      </TabPanel>
    </Route>
  ));

任何帮助将不胜感激,并提前致谢。

【问题讨论】:

标签: reactjs routes tabs react-router-dom


【解决方案1】:

一段时间以来,我一直在尝试做同样的事情,并且我得到了它(几乎)。每当标签发生变化时,我都会在 switchTabs 回调 (&lt;Tabs onChange={switchTabs}&gt;) 中触发写入 window.location.hash 的 URL 片段,并使用 window.addEventListner('hashchange', () =&gt; setTab(window.location.hash.slice(1))) 事件通过 React 钩子更新标签状态。一切正常,BackForward 按钮也可以正常工作。唯一的问题是服务器看不到 URL 片段(URL 的哈希 (#) 部分),所以如果您尝试使用在您的 URL 中添加哈希值,它最初将是默认值,并且客户端必须在页面加载后立即重新呈现。那是我卡住的部分。如果您不使用服务器端渲染,这可能不是问题,您可以这样做

const [currentTab, setTab] = useState(window.location.hash.slice(1) || 'myDefaultTab')
const switchTabs = (_, newTab) => {
  if (window.loaction.hash !== `#${newTab}`)
    window.location.hash = `#${newTab}`
  setTab(newTab)
}
window.addEventListner('hashchange', () => {
  setTab(window.location.hash.slice(1))
})
// ... then in your <Tabs> component
<Tabs value={currentTab} onChange={switchTabs}>
  // ...
</Tabs>

我决定改为使用对服务器可见的 URL 样式,以便可以将初始 useState 设置为 URL 查询参数。 Insetead 我使用了?tab=myTabName,这在使用服务器端渲染时效果更好。如果您有兴趣:

// ... in render function: (initialTab is from the server query params)
const [currentTab, setTab] = useState(initialTab)
const switchTab = (_, newTab: string) => {
    setTab(newTab)
    if (typeof window !== 'undefined')
        window.history.pushState(null, null, `?tab=${newTab}`)
}
if (typeof window !== 'undefined') {
    window.addEventListener('popstate', () => {
        const params = new URLSearchParams(window.location.search)
        const newTab = params.get('tab')
        if (newTab) setTab(newTab)
    });
}

这很好用,导航按钮(历史)、链接、刷新等。 这不使用Router 或其他任何东西,而且非常基本,但话又说回来,# URL 片段纯粹是客户端。

【讨论】:

  • 感谢您的努力@Sammy。似乎我们得到了相同的解决方案。这里是my example
猜你喜欢
  • 1970-01-01
  • 2017-05-29
  • 2019-01-28
  • 2021-11-26
  • 2018-12-19
  • 2014-04-12
  • 2020-11-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多