【问题标题】:React router goes to proper URL but does not update the viewReact 路由器转到正确的 URL 但不更新视图
【发布时间】:2020-11-19 18:13:10
【问题描述】:

我在我的 React 应用程序中使用 React Router 来跟踪食谱。此处的组件正在为每个配方卡生成链接,然后将显示所选配方的详细信息页面。当我单击卡片中的链接时,我会转到正确的 URL,但视图不会显示组件中的内容,而是仅显示来自基本 URL 的主屏幕组件。我需要进行哪些更改才能使 URL recipe/{id} 真正显示组件?

export default function RecipeReviewCard(props) {
  const classes = useStyles();
  return (
    // TODO: Make this link to the actual recipe detail screen.
    <div>
      <Link to={'recipe/' + props.recipe.id}>
        <Card className={classes.root}>
          <CardHeader
            title={props.recipe.title}
            subheader={props.recipe.prepTime}
          />
          <CardMedia
            className={classes.media}
            image={props.recipe.imageURL}
            title={props.recipe.title}
          />
          <CardContent>
            <Typography variant='body2' color='textSecondary' component='p'>
              {props.recipe.description}
            </Typography>
          </CardContent>
        </Card>
      </Link>
      <Switch>
        <Route exact path={'recipe/' + props.recipe.id}>
          <RecipeDetail />
        </Route>
      </Switch>
    </div>
  );

第二个组件是父类,它也使用路由器为应用程序中的主导航栏定义一些路径。也许我的路线的优先级有问题,由于某种原因,它采用默认的“/”路线而不是其他路线。

export default function PermanentDrawerLeft() {
  const classes = useStyles();

  // TODO: Fix font/style on the nav bar buttons.
  return (
    <div className={classes.root}>
      <AppBar position='fixed' className={classes.appBar}>
        <Toolbar>
          <Typography variant='h6' noWrap>
            <Switch>
              <Route path='/'>Kitchen Assistant</Route>
              <Route path='/cookbooks'>Cookbooks</Route>
              <Route path='/search'>Search</Route>
              <Route path='/settings'>Settings</Route>
            </Switch>
          </Typography>
        </Toolbar>
      </AppBar>
      <Drawer
        className={classes.drawer}
        variant='permanent'
        classes={{
          paper: classes.drawerPaper,
        }}
        anchor='left'
      >
        <div className={classes.toolbar} />
        <Divider />
        <Link to='/cookbooks'>
          <ListItem button key={'Cookbooks'}>
            <ListItemIcon>
              <MenuBookIcon />
            </ListItemIcon>
            <ListItemText primary={'Cookbooks'} />
          </ListItem>
        </Link>
        <Link to='/search'>
          <ListItem button key={'Search'}>
            <ListItemIcon>
              <SearchIcon />
            </ListItemIcon>
            <ListItemText primary={'Search'} />
          </ListItem>
        </Link>
        <Divider />
        <Link to='/settings'>
          <ListItem button key={'Settings'}>
            <ListItemIcon>
              <SettingsIcon />
            </ListItemIcon>
            <ListItemText primary={'Settings'} />
          </ListItem>
        </Link>
      </Drawer>
      <main className={classes.content}>
        <div className={classes.toolbar} />
        <Switch>
          <Route path='/cookbooks'>
            <Cookbooks />
          </Route>
          <Route path='/search'>
            <Search />
          </Route>
          <Route path='/settings'>
            <Settings />
          </Route>
          <Route path='/'>
            <Home />
          </Route>
        </Switch>
      </main>
    </div>

【问题讨论】:

  • 我认为我们需要看看外部路由是如何定义的。这里没有足够的上下文。我敢打赌,家乡路线具有更高的优先级并且首先渲染。
  • 好点,所以这个组件是另一个组件的子组件,它是定义主要路由的地方,例如主页。我将编辑我的帖子以添加该组件。如何告诉路由器不要优先考虑家乡路由?
  • 您使用的是哪个Router?你是怎么导入的?

标签: reactjs react-router


【解决方案1】:

您的路线声明很可能会遇到特殊性问题。您需要在不想级联的路由上指定 exact 布尔值。

举个例子:

<Route path='/' component={Home} />

总是匹配,但是:

<Route exact path='/' component={Home} />

仅当您位于 http://www.yoursite.com 而不是 http://www.yoursite.com/recipes 时才匹配。

查看here 的文档。

【讨论】:

  • 谢谢,这很有帮助。将精确添加到 path='/' 使其退出显示主组件,但它仍然不会显示我希望看到的 组件...
【解决方案2】:

Switch

呈现与匹配的第一个子 &lt;Route&gt;&lt;Redirect&gt; 位置。

这意味着您可以在您的Routes 上使用exact 属性,也可以先指定更多 特定路径,即“/pathA/pathB”在“/pathA”之前。

<Switch>
  <Route path='/cookbooks'>Cookbooks</Route>
  <Route path='/search'>Search</Route>
  <Route path='/settings'>Settings</Route>
  <Route path='/'>Kitchen Assistant</Route> // <-- move less specific "/" to end
</Switch>

这可以让你的根路由组件正确显示。

为了让您的RecipeDetail 组件渲染它需要在基础路由器中,以便RecipeReviewCard 在安装时显示指向其路径的链接。 p>

<Switch>
  <Route path='/cookbooks'>
    <Cookbooks />
  </Route>
  <Route path='/search'>
    <Search />
  </Route>
  <Route path='/settings'>
    <Settings />
  </Route>
  <Route exact path='recipe/:recipeId'> // <-- specify path and match param
    <RecipeDetail />
  </Route>
  <Route path='/'>
    <Home />
  </Route>
</Switch>

为了让RecipeDetail 可能加载正确的页面,它需要从route-props 中提取匹配参数。

For class-based components or any component directly rendered by the `Route` or wrapped with the [`withRouter`][3] Higher Order Component

props.match.params.recipeId

如果在功能组件中使用useParams 钩子

const { recipeId } = useParams();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-08
    • 1970-01-01
    • 2017-10-09
    • 2017-12-15
    • 1970-01-01
    • 2018-07-25
    相关资源
    最近更新 更多