reactjs - 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>
);
}
解决方案
在这里找到答案: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>
);
}
推荐阅读
- azure - 使用负载均衡器的天蓝色会话管理
- javascript - 用于发布包含 HTML 输入数组的表单数据的 JavaScript 函数
- windows - Lua io.popen() - 在 Windows 上访问共享驱动器
- lua - 尝试使用 Position 索引 nil
- r - 如何在闪亮的modalDialog中呈现不同的表格
- reactjs - Redux 调度 index.html 的内容
- python - Python:设置递归限制减慢排序程序
- mne-python - python mne 原始对象是否代表一条线索?如果是这样,如何在多次试验中取平均值?
- regex - (regex,sed) 擦除单词后如何附加擦除的单词
- winapi - 是否有保留的线程 ID 值?