无法在 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 路由器中正确地为路径添加前缀的主要内容,如果未能解决你的问题,请参考以下文章

Zuul路由转发规则

无法获取 API URL 以重新路由到正确的地址:React Hooks

在 Laravel 中添加前缀路由名称而不添加前缀 URI

如何设置 nginx 以正确地为 React 和 Django 提供服务

Ospf 路由选路的问题

React Router 未路由到 Route 元素中指定的路径