使用参数 id 对路由器路由做出反应

时间:2021-01-11 05:06:18

标签: javascript reactjs react-router

我在路由内部传递参数时遇到问题。 目前,我有以下路线:

<Route component={CategoriesPage} path={`/${AllRoutesEnum.COURSES}`} exact/>
<Route component={CoursesPage} path={`/${AllRoutesEnum.COURSES}/:id`} exact/>
<Route component={SectionPage} path={`/${AllRoutesEnum.COURSES}/:id/:id`} exact/>

所以 SectionPage 路由看起来像这样:courses/k-8-grades/early-math

我想做的事情

  • 当到达部分页面时,添加一个新的 id 参数。视频课程 ID。 所以应该是:courses/k-8-grades/early-math/videoId
  • 点击按钮概览时。添加网址#overview。所以应该是courses/k-8-grades/early-math/videoId#overview。
  • 点击按钮搜索时。删除网址#overview 添加#search。所以这将是课程/k-8-grades/early-math/videoId#search

我尝试过的:

  • 使用重定向。当到达 SectionPage 以某种方式传递 id 以重定向。但它失败了,因为路由没有正确匹配。
<Redirect from={`/${AllRoutesEnum.COURSES}/:id/:id/`} to={`/${AllRoutesEnum.COURSES}/:id/:id/test`} />
 {/* courses/early-math/early-math/test */}
<Route component={SectionPage} path={`/${AllRoutesEnum.COURSES}/:id/:id/`} exact/>
{/* courses/k-8-grades/early-math */}
  • 在部分页面中添加课程 ID onInit。但是如果我手动添加它
import { useHistory } from "react-router-dom";
const history = useHistory();
history.push('fdfdf');

什么时候会变成courses/k-8-grades/fdfdf而不是courses/k-8-grades/early-math/fdfdf

更新 所以我想出的是创建一个 SectionRedirect 页面:

<Route component={CategoriesPage} path={`/${AllRoutesEnum.COURSES}`} exact />
<Route component={CoursesPage} path={`/${AllRoutesEnum.COURSES}/:a`} exact />
<Route component={SectionRedirectPage} path={`/${AllRoutesEnum.COURSES}/:a/:b/`} exact />
<Route component={SectionPage} path={`/${AllRoutesEnum.COURSES}/:a/:b/:id`} exact />

Section 重定向页面推送 videoID。因为我需要在获取正确的视频 ID 课程/k-8-grades/early-math 之前命名路径。

props.history.push(`${location.pathname}/${videoId}`);

在部分页面中,我使用了喜欢的建议并且效果很好。

props.history.push({ hash: "overview" })

不幸的是,它并没有完全解决我的问题: 预期行为: 目前在访问部分页面时,我的网址是这样的:

courses/k-8-grades/early-math/videoId1#overview

点击第二个视频链接应该将网址更改为:

courses/k-8-grades/early-math/videoId2#overview

现实生活中的例子是 udemy 视频播放器。

使用以下方法找到解决方案: 在section.page

history.push({
      pathname: '/courses/k-8-grades/early-math/videoId'
    })

1 个答案:

答案 0 :(得分:1)

我认为主要问题是您使用 :id 引用了路径的两个可变部分。

您正在尝试将 courses/k-8-grades/early-math/ 映射到 courses/:id/:id/

相反,我认为您应该将其映射到以下形式:courses/:a/:b/

要将 #overview#search 添加到路径中,您可以这样做:

history.push({ hash: "overview" })

示例实现:

function App() {
  return (
    <Router>
      <Switch>
        <Route
          component={CategoriesPage}
          path={`/${AllRoutesEnum.COURSES}`}
          exact
        />
        <Route
          component={CoursesPage}
          path={`/${AllRoutesEnum.COURSES}/:id`}
          exact
        />
        <Redirect
          exact
          from={`/${AllRoutesEnum.COURSES}/:a/:b/`}
          to={`/${AllRoutesEnum.COURSES}/:a/:b/videoId`}
        />
        <Route
          component={SectionPage}
          exact
          path={`/${AllRoutesEnum.COURSES}/:a/:b/videoId`}
        />
      </Switch>
    </Router>
  );
}

function SectionPage() {
  const history = useHistory();

  return (
    <div>
      <button onClick={() => history.push({ hash: "overview" })}>
        overview
      </button>
      <button onClick={() => history.push({ hash: "search" })}>search</button>
    </div>
  );
}

Example as sandbox.