首页 > 解决方案 > React Router - 路由不使用片段

问题描述

react 和 javascript 相对较新,但试图组织一个项目,其中一些路由是从不同的常量中提取的,因此我可以在另一个文件中使用它们,以便有人可以在单独的模块上开发和测试,而无需完整的应用程序(伪微前端类型的东西)。这可能是过度工程,但基本上,当我将路由放入 const 并从其他地方引用它们时,我的 const 引用下方的任何路由都只会加载空白页面而不是组件或 html。

任何指导将不胜感激。

(反应 17.0.2 和反应路由器 dom 5.1.2)

路线.js):

import { BrowserRouter, Route, Switch, Redirect } from "react-router-dom";
import * as Yup from 'yup';
import Location from 'app-location';
import * as profile from '@profile-views';
import * as view from "modules/app/views";
...

const PROFILE_ROOT = `/profile`;

const userId = Yup.string();

/* Profile Routes */
export const Profile = new Location(
    `${PROFILE_ROOT}/:userId`, 
    { 
      userId: userId.required()
    }
  );
export const ProfileContactInfo = new Location(
  `${Profile.path}/contact`, 
  { userId: userId.required()}, 
);
export const ProfileCalendar = new Location(
  `${Profile.path}/calendar`, 
  { userId: userId.required()}, 
);
...
export const renderRoutes = (
  <>
      {/* everything works if Route components are in Routes() */}
    <Route exact path={Profile.path} component={profile.Timeline}/>
    <Route path={ProfileCalendar.path} component={profile.Calendar}/>
    <Route path={ProfileContactInfo.path} component={profile.ContactInfo}/>
  </>
)

export default function Routes() {
  return (
    <BrowserRouter>
      <Switch>
        <Route path="/login" component={view.Login} />
        { renderRoutes }
        {/* EVERYTHING ABOVE WORKS */}
        {/* EVERYTHING BELOW renderRoutes DOES NOT WORK */}
        {/* everything below works if i remove renderRoutes */}
        {/* everything works if i copy Routes from renderRoutes here */}
        <Route path="/create-user" component={view.CreateUser} />
        <Route path="/404" component={() => <h1>Not Found!</h1>} />
        <Redirect to="/404" />
      </Switch>
    </BrowserRouter>
  );
}

应用程序.js:

import Routes from "./routes";
...
function App() {
    return (
        <UserProvider>
            <Routes />
        </UserProvider>
    );
}

标签: reactjsreact-router

解决方案


在这里找到答案:https ://github.com/ReactTraining/react-router/issues/5785

Switch 组件不喜欢将片段作为子组件进行反应。解决方法似乎是向 Switch 添加一个包装器组件以删除片段。

根据链接更新了以下内容,一切正常。

import React, { Fragment } from 'react';

...

export const FragmentSupportingSwitch = ({children}) => {
  const flattenedChildren = [];
  flatten(flattenedChildren, children);
  return React.createElement.apply(React, [Switch, null].concat(flattenedChildren));
}

function flatten(target, children) {
  React.Children.forEach(children, child => {
    if (React.isValidElement(child)) {
      if (child.type === Fragment) {
        flatten(target, child.props.children);
      } else {
        target.push(child);
      }
    }
  });
}

...

export default function Routes() {
  return (
    <BrowserRouter>
      <FragmentSupportingSwitch>
        <Route path="/login" component={view.Login} />
        { renderRoutes }
        <Route path="/create-user" component={view.CreateUser} />
        <Route path="/404" component={() => <h1>Not Found!</h1>} />
        <Redirect to="/404" />
      </FragmentSupportingSwitch>
    </BrowserRouter>
  );
}

推荐阅读