问题描述
我有一个带有 IonReactRouter
的 Ionic/React v5.0.7 应用来管理路由:
// App.tsx
return (
<IonApp>
<IonReactRouter history={history}>
<IonRouterOutlet>
<Route exact path={ROUTES.HOME} component={Home} />
<Route exact path={ROUTES.LOGIN} component={Login} />
<Route path={ROUTES.CONTRACTOR} component={ContractorDashboard} />
</IonRouterOutlet>
</IonReactRouter>
</IonApp>
)
在我的一条路线 (path={ROUTES.CONTRACTOR}
) 中,我试图实现 IonTabs
,它需要有自己的 IonRouterOutlet
,所以我将选项卡作为嵌套路线,如下所示:
// ContractorDashboard.tsx
<IonContent>
<IonTabs>
<IonTabBar slot="top">
<IonTabButton href="/contractor/overview" tab="contractor-overview">
<IonLabel>{t('ContractorDashboard.contractorOverview')}</IonLabel>
</IonTabButton>
<IonTabButton href="/contractor/contractor-configs" tab="contractor-configs">
<IonLabel>{t('ContractorDashboard.contractorConfig')}</IonLabel>
</IonTabButton>
<IonTabButton href="/contractor/workers-management" tab="workers-management">
<IonLabel>{t('ContractorDashboard.workersManagement')}</IonLabel>
</IonTabButton>
<IonTabButton href="/contractor/email-responses" tab="email-responses">
<IonLabel>Some label</IonLabel>
</IonTabButton>
</IonTabBar>
<IonRouterOutlet>
<Route path="/contractor/contractor-configs" render={() => <ContractorConfigs userId={authUser.uid} />} />
<Route path="/contractor/workers-management" component={WorkersManagement} />
<Route path="/contractor/email-responses" render={() => <EmailResponses userId={authUser.uid} />} />
<Route path="/contractor/contractor-overview" render={() => <IonTitle>Title</IonTitle>} />
<Route exact path="/contractor" render={() => <Redirect to="/contractor/overview" />} />
</IonRouterOutlet>
</IonTabs>
</IonContent>
一切正常,直到我尝试使用 /contractor
或 history.push('/contractor')
创建到 <Redirect to="/contractor" />
路由的动态导航,该路由是选项卡路由器的根。
在我的登录组件中,如果用户通过身份验证,我想自动重定向到 ContractorDashboard
。 IE。成功登录后,用户应该被重定向到仪表板。我实现了以下内容:
// Login.tsx
useEffect(() => {
if (authUser) {
history.push('/contractor')
}
},[authUser,history])
发生的情况是地址栏中的 URL 已更改,但登录页面仍然可见,而不是 ContractorDashboard
。我也试过这个:
// Login.tsx
if (authUser) {
return <Redirect to="/contractor"/>
}
return (
// ...
)
结果是一样的。我可以在开发工具中看到承包商页面,但未呈现。
一些注意事项:
- 当我尝试不同的事情时,结果会有所不同,例如推送到
/contractor/overview
而不是仅/contractor
。然后承包商仪表板会显示一秒钟,然后又是登录页面。 - 有时我会看到仪表板,但选项卡不可见。它在 DOM 中,光标事件在那里,但仍然不可见。
- 在仪表板中使用
IonTabs
之前一切正常。 - 奇怪的是,当我尝试使用经过身份验证的用户通过地址栏导航到登录页面时,我被重定向到仪表板,一切正常。
我确实尝试用 IonReactRouter
中的 Router
替换 react-router
,就像 this answer 中建议的那样。然后从登录页面重定向有效,但标签会在每次标签更改时触发整页刷新,这简直是糟糕的用户体验。
这是我的 ionic info
输出:
Ionic:
Ionic CLI : 6.11.0
Utility:
cordova-res : not installed
native-run : not installed
System:
NodeJS : v12.18.3
npm : 6.14.6
OS : Windows 10
这是我的package.json
:
{
"name": "application","version": "0.0.1","private": true,"dependencies": {
"@capacitor/android": "^2.4.6","@capacitor/core": "2.4.6","@ionic/react": "^5.0.7","@ionic/react-router": "^5.0.7","@testing-library/jest-dom": "^4.2.4","@testing-library/react": "^9.4.0","@testing-library/user-event": "^8.0.3","@types/jest": "^24.0.25","@types/node": "^12.12.24","@types/react": "^16.9.17","@types/react-dom": "^16.9.4","@types/react-router": "^5.1.4","@types/react-router-dom": "^5.1.3","firebase": "^8.2.3","i18next": "^19.8.4","i18next-http-backend": "^1.0.22","ionicons": "^5.0.0","react": "^16.13.0","react-dom": "^16.13.0","react-i18next": "^11.8.5","react-redux": "^7.2.2","react-router": "^5.1.2","react-router-dom": "^5.1.2","react-scripts": "^4.0.1","redux": "^4.0.5","redux-localstorage-simple": "^2.3.1","redux-thunk": "^2.3.0","typescript": "3.8.3"
},"scripts": {
"start": "react-scripts start","build": "react-scripts build","test": "react-scripts test","eject": "react-scripts eject","appium": "appium --chromedriver-executable C:\\Users\\Ori\\code\\chromedrivers\\chromedriver-83-0-4103.exe","e2e:android": "protractor e2e/android-e2e.conf.js","e2e:web": "protractor e2e/web-e2e.conf.js"
},"eslintConfig": {
"extends": "react-app"
},"browserslist": {
"production": [
">0.2%","not dead","not op_mini all"
],"development": [
"last 1 chrome version","last 1 firefox version","last 1 safari version"
]
},"devDependencies": {
"@capacitor/cli": "2.4.6","@types/jasmine": "^3.6.3","@types/jasminewd2": "^2.0.8","@types/react-redux": "^7.1.15","@types/redux-logger": "^3.0.8","appium": "^1.20.2","jasmine": "^3.6.4","jasmine-spec-reporter": "^6.0.0","protractor": "^7.0.0","redux-logger": "^3.0.6","ts-node": "^9.1.1"
},"description": "An Ionic project"
}
那么有没有办法正确实现这一点以及如何实现?
如果此处缺少任何信息或代码,请告诉我。
任何帮助将不胜感激!
更新
所以对于任何有兴趣的人,我放弃了寻找解决方案。相反,我实现了自己的基本选项卡,没有路由(一直不明白为什么选项卡需要路由......)。
不考虑样式很简单:
const [tab,setTab] = useState<number>(0);
const mapTabs = [
'contractorOverview','contractorConfigs','workersManagement','emailResponses'
]
const handleTabChange = () => {
switch (tab) {
case 0: return <h3>Overview</h3>;
case 1: return authUser && <ContractorConfigs userId={authUser.uid} />;
case 2: return <WorkersManagement />;
case 3: return authUser && <EmailResponses userId={authUser.uid} />;
default: return <h3>Overview</h3>;
}
}
return (
// ....
<IonContent>
<IonToolbar color="secondary">
<IonButtons slot="start">
{mapTabs.map((_tab,tabIdx) => (
<IonButton
key={tabIdx}
id={`${_tab}`}
onClick={() => setTab(tabIdx)}
disabled={mapTabs[tab] === _tab}
>
{t(`ContractorDashboard.${_tab}`)}
</IonButton>
))}
</IonButtons>
</IonToolbar>
{handleTabChange()}
</IonContent>
// ....
)
这就是拥有一个工作标签视图所需的全部内容(同样,如果没有一些样式,它看起来不会那么好看)。
如果有人有选项卡问题的解决方案(实际上我不是 100% 确定是什么导致了问题......我无法在 stackblitz 中重现......)我很想听听。
如果没有,我会将此作为答案发布...
解决方法
你试过了吗:
Crosswalk_id C1 C2 C3 C4 C5 C6
ORG_201 1234 3456 3459 0983 2562 1239
或
history.push({ pathname: '/contractor' })
,
你有没有试过...
history.push('/contractor/overview')
你能在 stackblitz 或 codeandbox 上发布一个小项目吗?