我正在创建一个项目,其中我希望URL保存一个id.该id将用于从数据库中获取有关具有该id的项的信息,并将其呈现在页面上.我已经成功地实现了基于url中的id的数据加载.

我的问题是react 路由DOM似乎将ID为的URL解释为未知的路由,并将其重定向到我的错误页面.

我的路由是这样设置的:

const router = createBrowserRouter([
  {
    path: "/",
    element: <Root />,
    errorElement: <Error />,
    children: [
      { path: "/", element: <Home /> },
      { path: "progress", element: <Progress /> },
      { path: "logworkout", element: <LogWorkout /> },
      {
        path: "programs",
        element: <Programs />,
        children: [
          { index: true, element: <Navigate to="myprograms" replace /> },
          { path: "discover", element: <DiscoverPrograms /> },
          {
            path: "myprograms",
            element: <MyPrograms />,
            children: [
              {
                path: ":programID",
                element: <ProgramView />,
                loader: programViewLoader,
              },
            ],
          },
        ],
      },
      { path: "product", element: <Product /> },
      { path: "contact", element: <Contact /> },
    ],
  },
]);

我基本上希望呈现/Programs/MyPrograms/:ProgramID,而不是错误页面.我想我已经很好地遵循了关于REACT-ROUTER-DOM文档的教程,但是我不知道我遗漏了什么.

编辑:/programs中只有<Programs/>会呈现Outlet

import { Outlet } from "react-router-dom";

const Programs = () => {
  return (
    <div className="grid overflow-hidden" style={{gridTemplateColumns: "auto 1fr"}}>
      <SideBar />
      <div className="overflow-auto">
        <Outlet />
      </div>
    </div>
  );
};

export default Programs;

编辑:问题不是关于动态路由,而是关于我在<ProgramView/>上使用的加载器函数.显然,我不会在加载器中返回值.

import Cookies from "js-cookie";
import { refreshToken } from "../../../../util/auth";

export const programViewLoader = ({ params }) => {
  refreshToken()
    .then((refresh) => {
      return fetch("http://localhost:5000/program/load-program", {
        method: "POST",
        headers: {
          "Content-type": "application/json",
          Authorization: `Bearer ${Cookies.get("accessToken")}`,
        },
        body: JSON.stringify({
          programID: params.programID,
        }),
      });
    })
    .then((response) => {
      if (!response.ok) {
        return response.json().then((data) => {
          throw { error: data.error, status: response.status };
        });
      }
      return response.json();
    })
    .then((data) => {
      console.log(data.program);
      return data.program;
    })
    .catch((error) => {
      return { error: "An error occurred while loading the program." };
    });
};

然而,console.log()总是打印一些东西,所以我不确定它为什么不返回任何东西

推荐答案

"/programs"中只有<Programs />会导致Outlet

这只允许将101个嵌套的路由呈现到父路由组件的Outlet中,例如:

  • "/programs"索引路由上是Navigate
  • "/programs/discover"%为DiscoverPrograms%
  • "/programs/myprograms"%为MyPrograms%

这些组件中的任何一个都需要为它们可能正在呈现的任何嵌套路由再呈现Outlet个它们自己的组件.

const MyPrograms = () => {
  ...

  return (
    ...

    <Outlet />

    ...
  );
};

现在,ProgramView应该可以通过MyProgramsOutletProgramsOutlet"/programs/myprograms/:programID"上渲染.

programViewLoader没有返回值.refreshToken函数返回一个Promise Chain,但是您需要从加载器函数实际返回Promise Chain的结果.

export const programViewLoader = ({ params }) => {
  return refreshToken() // <-- return Promise chain!
    .then((refresh) => {
      return fetch("http://localhost:5000/program/load-program", {
        method: "POST",
        headers: {
          "Content-type": "application/json",
          Authorization: `Bearer ${Cookies.get("accessToken")}`,
        },
        body: JSON.stringify({
          programID: params.programID,
        }),
      });
    })
    .then((response) => {
      if (!response.ok) {
        return response.json().then((data) => {
          throw { error: data.error, status: response.status };
        });
      }
      return response.json();
    })
    .then((data) => {
      console.log(data.program);
      return data.program;
    })
    .catch((error) => {
      return { error: "An error occurred while loading the program." };
    });
};

Reactjs相关问答推荐

如何避免react 使用ESLINTreact 挂钩/穷举-deps进行第一次呈现

根据另一个Select中的选定值更改Select中的值

使用useReducer时,props 未从父级传递给子或孙级

我应该如何管理设置组件初始状态的复杂逻辑?

在REACT-RUTER-DOMV6中使用通用页面包装组件有问题吗?

Mantine DatePickerInput呈现错误

Material-UI 和 React Hook 表单不记录值

列表中的每个子项都应该有一个唯一的keyprops .在react 应用程序中

在 useSelector() 中使用 array.map() 如何导致组件在分派操作时重新渲染?

Redux 工具包不更新状态

Chakra UI:如何在选中状态下设置复选框 colored颜色

基于 React/NextJS Timer 的文本淡入/淡出不起作用

在 CrafterCMS Studio 中拖动字段

我应该如何将字符串作为props 传递给 React 组件?

如何禁用 redux-toolkit 的不可序列化值测试警告?

在 React 的父级中多次调用子级时从子级获取数据到父级

在 Spring Cloud Gateway 中运行的 React SPA 页面刷新出现白标错误

使用 React 中的功能组件更改另一个组件的状态

如何使用 useEffect 和 if 语句 React

如果两个组件在 React 中导入相同的 CSS 文件会发生什么?