1

我正在尝试将 slug 传递给标题组件,而不必将标题包含到每个子组件中。

我的代码如下所示:

const App = () => {
  return (
    <>
      <Grid container direction="column">
        <Grid item>
          <Header />
        </Grid>
        <Grid item container>
          <Grid item xs={false} md={2} />
          <Grid item xs={12} md={8}>
            <Switch>
              <Route exact path="/" component={IntroPage} />
              <Route exact path="/:slug" component={StartPage} />
              <Route path="/:slug/index" component={StartPage} />
              <Route path="/:slug/player" component={PlayerPage} />
              <Route path="/:slug/game" component={GamePage} />
              <Route path="/:slug/scoreboard" component={ScoreboardPage} />
              <Route path="/:slug/controller" component={ControllerPage} />
              <Route path="/:slug/settings" component={SettingsPage} />
              <Route path="/:slug/credits" component={CreditsPage} />
              <Route component={PageNotFound} />
            </Switch>
          </Grid>
          <Grid item xs={false} md={2} />
        </Grid>
        <ToastContainer autoClose={3000} hideProgressBar />
      </Grid>
      <Grid container direction="column">
        <Footer />
      </Grid>
    </>
  );
};

export default App;

我想要的是 Header 组件来了解在 Switch 的其中一条路由中选择了哪些 slug。

例如嵌套路由是否有可能做到这一点?

最好的问候,帕特里克


编辑:

这是我的 Header 组件顺便说一句:

const Header = (props) => {
  console.log(props.match.params.slug)
  const classes = useStyles();
  const [open, setOpen] = useState();

  const handleDrawerOpen = () => {
    setOpen(true);
  };

  const handleDrawerClose = () => {
    setOpen(false);
  };

  return (
    <div className={classes.root}>
      <AppBar
        position="static"
        className={clsx(classes.appBar, { [classes.appBarShift]: open })}
      >
        <Toolbar>
          <IconButton
            aria-label="open drawer"
            onClick={handleDrawerOpen}
            edge="start"
            className={clsx(classes.menuButton, open && classes.hide)}
          >
            <MenuIcon />
          </IconButton>
          <Typography>Placeholder Banner</Typography>
        </Toolbar>
      </AppBar>
      <Drawer
        variant="persistent"
        anchor="left"
        open={open}
        className={classes.drawer}
        classes={{ paper: classes.drawerPaper }}
      >
        <div className={classes.drawerHeader}>
          <IconButton onClick={handleDrawerClose}>
            <CloseIcon />
          </IconButton>
        </div>
        <Divider />
        <List>
          <ListItem component="a" href="/" button key="start">
            <ListItemIcon>
              <HomeIcon fontSize="large" />
            </ListItemIcon>
            <ListItemText>Start</ListItemText>
          </ListItem>
          <ListItem component="a" href="/game" button key="game">
            <ListItemIcon>
              <SportsEsportsIcon fontSize="large" />
            </ListItemIcon>
            <ListItemText>Game Setup</ListItemText>
          </ListItem>
          <ListItem component="a" href="/player" button key="player">
            <ListItemIcon>
              <PersonIcon fontSize="large" />
            </ListItemIcon>
            <ListItemText>Player Setup</ListItemText>
          </ListItem>
          <ListItem component="a" href="/settings" button key="settings">
            <ListItemIcon>
              <SettingsIcon fontSize="large" />
            </ListItemIcon>
            <ListItemText>Settings</ListItemText>
          </ListItem>
          <ListItem component="a" href="/credits" button key="credits">
            <ListItemIcon>
              <InfoIcon fontSize="large" />
            </ListItemIcon>
            <ListItemText>Credits</ListItemText>
          </ListItem>
        </List>
      </Drawer>
    </div>
  );
};

export default Header;

我想让链接能够包含蛞蝓。例如href=/game需要href=:slug/game然后。

请注意,标题是在切换之前加载的。


编辑2:

至少这样:

const Header = (props) => {
  const {match, location, history} = props
  console.log(match)
  console.log(location)
  console.log(history)

....

export default withRouter(Header);

将让我访问有蛞蝓的位置。但这似乎不是最干净的方法。withRouter即使使用导出,match.params 也不会保留 slug 。这是为什么?

我的解决方案,直到我知道更好(不工作)

const Header = (props) => {
  const { location } = props;
  let pathname = location.pathname
  let slug = pathname.split("/")
  console.log(slug[1]);

....


export default withRouter(Header);

这将导致在单击几下后 url 变得混乱,因为 location 将一次又一次地连接起来,从而导致诸如 /myslug、game、player 之类的 ins url。

最终解决方案

好吧,我从下面得到了最终解决方案:

将 Header 的特定位置包装到 Route

        <Grid item>
          <Route path={["/:slug", "*"]} component={Header} />
        </Grid>

然后访问 Header 组件中的 props.match.params :

const Header = (props) => {
  console.log(props.match.params)

这将给出:

slug: "game"
4

3 回答 3

2

问题

没有在路由上呈现,因此Header它无法访问任何路由道具,特别是路由参数。它还需要在与指定“slug”路由参数的路径匹配的路由上呈现。

解决方案

将 渲染HeaderRoute指定匹配所有路径可以与 slug 匹配的路径。顺序很重要,因此首先使用 slug 指定路径,以便可以在不太具体的路由之前匹配它(与 的规则相同Switch)。

<Route path={["/:slug", '*']} component={Header} />
于 2020-08-17T08:18:27.600 回答
0

尝试使用 useParams() 来获取 slug。

于 2020-08-17T07:16:12.337 回答
0

尝试这样做:

<Route 
   exact 
   path='/:slug/player' 
   render={(props) => <PlayerPage {...props}/>}
/>
于 2020-08-17T07:44:11.253 回答