当前位置: 首页 > 知识库问答 >
问题:

React路由器不匹配链路或NavLink上的任何路由(但如果我们刷新,它会工作)

庄瀚玥
2023-03-14

今天我花了很多时间试图调试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
  }
}

我错过了什么?


共有2个答案

汪晟睿
2023-03-14

我知道问题是解决后切换到浏览器路由器,但只是为了了解实际问题。这是为那些真正想使用低级路由器的人准备的。问题出在您安装的历史包上。尝试使用以前的版本,如4.7.2,它允许您的导入默认导出创建历史从历史/创建浏览器历史,而不是直接从历史导入名为导出创建浏览器历史的最新版本。

根据我的经验,最新的历史记录只允许您在页面刷新时更改路由,对于navlink或link,它不处理任何路由,只更改url。

嗯,这都是希望它能帮助某人。

欧阳骏俊
2023-03-14

看起来您正在使用低级路由器组件。您可能想改用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中以为前缀。