今天我花了很多时间试图调试React路由器Dom的一个问题,但没有成功,所以我写这篇文章。我不知道发生了什么事。
在描述问题之前,下面是这里使用的包的版本:
React: ^16.6.3
react-dom: ^16.6.3
react-router-dom: ^5.2.0
我有一个React应用程序,它的根组件由ReactDOM.render
呈现。它为应用程序的两种基本情况呈现redux的提供者和路由器,具体取决于用户是否连接。
Root.tsx:
interface Props {
store: StoreType
}
const Root: FunctionComponent<Props> = ({ store }) => (
<Provider store={store}>
<Router history={history}>
<Route path="/login" component={Login} exact />
<Route path="/" component={Dashboard} />
<Route // this route was just been added to debug my problem
path="*"
render={props => {
console.log(props)
return <div>Hello</div>
}}
/>
</Router>
</Provider>
)
export default Root
Dashboard是一个布局容器,它呈现侧边栏、顶栏和主要部分,其中所有路由都在SwitchRoutes
组件中呈现。它从api中获取所需的数据,并在此过程中显示加载器。这是它的渲染函数。
Dashboard.js:
render() {
const { classes, ...rest } = this.props
if (!this.state.loader.appReady) {
return <CustomLoader ready={this.state.loader.dataFetched} />
}
if (this.props.users.redirectTo !== null) {
return <Redirect to={this.props.users.redirectTo} />
}
const { zones } = this.props
return (
<div className={classes.wrapper}>
<ErrorBoundary component="Sidebar">
<Sidebar
routes={dashboardRoutes(role().shift()).reduce(
sitesReducer(get(zones, "list").filter(zone => zone.zoneLevel.id === this.firstLevelZone)),
[]
)}
logo={logo}
toggleMenu={this.toggleMenu}
open={this.state.openedMenu}
color="red"
{...rest}
/>
</ErrorBoundary>
<div className={classes.mainPanel} ref="mainPanel">
<TopBar toggleMenu={this.toggleMenu}>{this.topbarContent}</TopBar>
<div className="spectral__layout-page-name default-font">
<h5>{this.pageName()}</h5>
</div>
<div className={classes.content}>
<div className={classes.container}>
{this.state.materialRoutes.length && (
<ErrorBoundary component="SwitchRoutes">
<SwitchRoutes materialRoutes={this.state.materialRoutes} />
</ErrorBoundary>
)}
</div>
</div>
</div>
</div>
)
}
和SwitchRoutes组件:
const SwitchRoutes = ({ materialRoutes }) => {
return (
<Switch>
{dashboardRoutes(role().shift()).map(prop => {
if (prop.redirect) return <Redirect from={prop.path} to={prop.to} key="redirect" />
if (prop.children && prop.children.length) {
return prop.children
.filter(c => c.onSidebar)
.map(c => {
return <Route exact={c.exact} path={c.path} component={c.component} key={`route_${c.path}`} />
})
}
if (prop.path.startsWith("/materials")) {
return (
<Route
path="/materials"
key="route__material_wrapper"
render={props => <MaterialIndexModule {...props} routes={materialRoutes} />}
/>
)
}
return <Route exact={prop.exact} path={prop.path} component={prop.component} key={`route_${prop.path}`} />
})}
<Route component={NotFound} path="*" />
</Switch>
)
}
如果我进行刷新,这将在本地呈现,因此我知道react router将与“/”匹配以呈现我的仪表板,然后是其他路由。但当我点击任何链接转到另一个页面时,仪表板就会卸载,剩下的就是呈现的根组件。相当混乱。渲染链接或导航链接的每个组件都使用react router dom的withRouter HOC导出,但它仍然无法渲染任何内容。
如果您需要更多信息,这里是我在SwitchRoutes和边栏中映射的数组仪表板路由的摘录:
const dashboardRoutes = role => [
{
name: "Home",
path: "/",
exact: true,
component: App,
onSidebar: false,
sidebarName: "",
navbarName: "",
icon: PinDrop,
},
{
name: "scenarios",
path: "/scenarios",
component: Scenarios,
exact: false,
onSidebar: true,
sidebarName: "Scenarios",
navbarName: "Scenarios",
icon: PinDrop,
},
{
name: "materials",
path: "/materials",
component: Materials,
onSidebar: true,
exact: false,
sidebarName: "Materials",
navbarName: "Materials",
}
]
如前所述,一旦应用程序呈现,我单击的任何链接都无法呈现仪表板,并向我发送我在根组件中添加的未找到路由。当我记录比赛和位置道具时,下面是打印的内容:
{
location: {
hash: ""
key: "koo33kue"
pathname: "/materials/rooms/18" // the route I wanted to reach
search: ""
state: null
},
match: {
params: {0: "undefined"},
url: "undefined",
path: "*",
isExact: false
}
}
我错过了什么?
我知道问题是解决后切换到浏览器路由器,但只是为了了解实际问题。这是为那些真正想使用低级路由器的人准备的。问题出在您安装的历史包上。尝试使用以前的版本,如4.7.2,它允许您的导入默认导出创建历史从历史/创建浏览器历史,而不是直接从历史导入名为导出创建浏览器历史的最新版本。
根据我的经验,最新的历史记录只允许您在页面刷新时更改路由,对于navlink或link,它不处理任何路由,只更改url。
嗯,这都是希望它能帮助某人。
看起来您正在使用低级路由器组件。您可能想改用BrowserRouter或MemoryRouter。
import { BrowserRouter } from 'react-router-dom';
const Root: FunctionComponent<Props> = ({ store }) => (
<Provider store={store}>
<BrowserRouter>
<Route path="/login" component={Login} exact />
<Route path="/" component={Dashboard} />
<Route // this route was just been added to debug my problem
path="*"
render={props => {
console.log(props)
return <div>Hello</div>
}}
/>
</BrowserRouter>
</Provider>
)
export default Root
Tango支持4种形式的路由匹配规则 静态路由 tg.Get("/", new(Action)) tg.Get("/static", new(Action))匹配 URL:/ 到 Action结构体的Get函数 匹配 URL:/static 到 Action结构体的Get函数 命名路由 tg.Get("/:name", new(Action)) tg.Get("/(:name)", new(Act
大家好,我不知道发生了什么事。我有以下路线: 只有路径为“/”的路由和路径为“/patient/:id”的路由才有效,其他3条路由只是没有显示与路径对应的组件。 这就是我进入路线的方式。我有一个标题组件,上面有正确的链接。见下文 在头组件中,我从'react router dom'导入{Link};在我声明路由的文件中,我从'react router dom'导入{BrowserRouter,Ro
问题内容: 我陷入了反应路由器路由。我收到错误消息: 这是我的 app.js : 我的 App.js 如下所示: 我的 Home.js 如下所示: 这是我的项目的层次结构: 如您所 料* ,我使用 browserify 构建 app.js 并创建 bundle.js, 并且在 index.html的 脚本标记中使用了 bundle.js * 这是我在项目中使用的所有版本。 因此,当我尝试转到“ h
要部署我的应用程序,我能想到的唯一方法是使用Tomcat。因此,我复制了项目的bundle.js和index.html文件,并将其放在eclipse IDE的WebContent中。下面是index.js文件: 因此,当我使用web pack dev server时,我的路由器工作正常,但当我将文件复制到eclipse项目的web content时(这将为我设置一切,并使项目可以使用这个Url h
如果我将路由折叠起来,这样看起来就像: 工作很好。我嵌套的原因是因为我将在“dashboard”下有多个子项,并且希望它们都在URL中以为前缀。