无法在 React 路由器中正确地为路径添加前缀
Posted
技术标签:
【中文标题】无法在 React 路由器中正确地为路径添加前缀【英文标题】:Can't add prefixes to paths properly in React router 【发布时间】:2018-02-17 05:16:49 【问题描述】:我正在创建多语言应用程序。我正在使用:React Intl;反应路由器(最新 v4); Redux. 我的应用程序中的路径将取决于语言环境:
/ <-- default expecting this to be uk
/en
/ru
/news <-- uk
/en/news
/ru/news
如果用户有locale = en-US
并输入localhost:8080
应用程序会将他重定向到localhost:8080/en
如果用户拥有locale = uk
并输入localhost:8080
,则应用会向他显示与地址localhost:8080/
对应的组件,而无需更改位置路径名。
Routers.jsx
const Routes = ( lang ) => (
<BrowserRouter basename=lang>
<Route render=props => <Header ...props /> />
<Switch>
<Route exact path=`/:$lang` component=Landing />
<Route exact path=`/:$lang/news` component=News />
<Route component=FourOhFour />
</Switch>
</BrowserRouter>
);
const mapStateToProps = state => ( lang: getLang(state.locale) );
export default connect(mapStateToProps)(Routes);
目前它没有按预期工作。
如果我输入localhost:8080/
或localhost:8080/en
,我会在路由配置中得到no match
。
【问题讨论】:
您需要这样做吗?或者你可以用其他方式吗?如果是,我建议使用对 i18n 有帮助的库 @HenriqueOeckslerBertoldi 我认为React-Intl
是一个有助于国际化 React 应用程序的库
是的,你是对的。但也许这个库会解决你的问题:react.i18next.com。您不要在路由中更改语言,而是直接在对象中更改语言,请参见:i18next.com/api.html#changelanguage
仅供参考。如果您的组件有子路由,请避免使用“确切路径”。(使用更严格的正则表达式的“路径”)
【参考方案1】:
这是我的解决方法。 重定向工作正常,并为 props 添加前缀。
Routers.jsx
const Routes = ( lang ) => (
<BrowserRouter>
<Route render=props => <Header lang=lang ...props /> />
<Switch>
<RootRouter
exact
path='/:lang(en|ru)?'
lang=lang
component=Landing
/>
<Route
exact
path='/:lang(en|ru)?/news'
render=props => <News ...props lang=lang />
/>
<Route component=FourOhFour />
</Switch>
</BrowserRouter>
);
const mapStateToProps = state => ( lang: getPrefix(state.locale) );
export default connect(mapStateToProps)(Routes);
RootRouter.jsx
const RootRouter = ( component: Component, exact, path, lang ) => (
<Route
exact=exact
path=path
render=(props: ContextRouter) =>
props.location.pathname === '/' && lang !== '' ? (
<Redirect to=`/$lang` />
) : (
<Component ...props lang=lang />
)
/>
);
标题组件 (Contacts.jsx) 中的方法在 Click 事件上更改语言环境:
const changeLang = newLang => () =>
if (lang !== newLang)
const newUrl = switchLangHepler(lang, newLang, location.pathname);
setLocaleData(newLang);
localStorage.setItem('lang', String(newLang));
history.replace(newUrl);
;
【讨论】:
【参考方案2】:带有 react-router 的 changeLanguage
函数:
changeLanguage(lang)
// Get the path without the language path
const oldPath = this.props.location.pathname.replace("en/", "").replace("fr/", "")
// new path, with the /en path (if english is asked)
const newPath = lang === "en" ? "/en" + oldPath : oldPath
this.setState(
redirect: newPath
)
// Change the language
i18n.changeLanguage(lang)
在渲染方法中:
render()
const redirect = this.state.redirect ? <Redirect to=this.state.redirect /> : null
return (
<UncontrolledDropdown>
redirect
<DropdownToggle nav caret>
this.props.lang === 'fr' ? "FR" : this.props.lang === 'en' ? "EN" : ''
</DropdownToggle>
<DropdownMenu right>
<DropdownItem onClick=() => this.changeLanguage("fr") >
Français
</DropdownItem>
<DropdownItem onClick=() => this.changeLanguage("en")>
English
</DropdownItem>
</DropdownMenu>
</UncontrolledDropdown>
)
【讨论】:
以上是关于无法在 React 路由器中正确地为路径添加前缀的主要内容,如果未能解决你的问题,请参考以下文章
无法获取 API URL 以重新路由到正确的地址:React Hooks