reactjs - Material-ui:使用尖锐(#)而不是斜杠(/)的路由选项卡
问题描述
我对 React 很陌生,我现在正在使用 ReactJS 和 material-ui 框架开发一个站点。
我的问题是如何像这个网站一样自定义标签链接网址
在这个网站上,当我切换选项卡按钮 url 时,添加#(a-custom-tab-link)
. 假设我在xxx/yyy
url 上,如果我切换名为 zzz 的选项卡,则 url 更改为xxx/yyy#zzz
.
我已经使用引用material-ui tabs docs 的material-ui tabs 组件制作了标签。而且我可以使用更改标签网址useRouteMatch
,代码示例在这里。
这是我的问题。
- 如何更改标签网址不是通过添加
/
而是在本网站上#
添加类似标签 - 如何将第一个选项卡的路由器设置为与其父路由器相同,以便自动显示。(我这样做没有考虑路由器,但如果我考虑在选项卡切换上更改路由器,我不能这样做)
这是我目前的代码片段。
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>
));
任何帮助将不胜感激,并提前感谢。
解决方案
一段时间以来,我一直在尝试做同样的事情,并且(几乎)可以正常工作。window.location.hash
每当标签发生变化时,我都会在switchTabs
回调 ( ) 中触发 URL 片段写入<Tabs onChange={switchTabs}>
,并使用window.addEventListner('hashchange', () => setTab(window.location.hash.slice(1)))
事件通过 React 钩子更新标签状态。所有这些都很好,Back和Forward按钮也可以。唯一的问题是服务器看不到 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片段纯粹是客户端。
推荐阅读
- excel - 在朋友计算机上加载 VBA 加载项的问题
- c# - SCA 的订阅付款必须启动并运行
- python-3.x - 如何分离子图上的数据?
- c# - 将 Unicode 字符转换回其原始字符串表示形式
- c# - 在调试和发布之间切换后,某些代码和断点不起作用
- tensorflow - 在 YOLO 中标注训练数据
- wordpress - 寻找软件,以便我可以使用基于 GIT 功能分支的临时 URL 启动一个快速测试站点
- sql - 更新 SELECT 查询中的列值
- spring - 为什么休眠实体图获取嵌套的惰性集合
- javascript - 如何在 Jest 中测试 Worker 的默认函数中的函数?