React Router基本使用

222 阅读1分钟

reactrouter.com/en/6.6.1/st…

路由,记录组件和路径的映射关系。后监听路径,当路径发生改变时,渲染相应的组件。

参考:blog.csdn.net/m0_70718568…

基本映射

一、全局挂载元素使用react-router

import {
  createBrowserRouter,
  RouterProvider,
} from "react-router-dom";

ReactDOM.createRoot(document.getElementById("root")).render(
    <RouterProvider router={router} />
);

二、配置映射关系

(一)、组件式映射关系

const router = createBrowserRouter(
  createRoutesFromElements(
    <>
    <Route path="/" element={<Root />}>
      <Route path="child1" element={<Child1 />} />
      <Route path="child2" element={<Child2 />} />
    </Route>
  	<Route path="/place" element={<Place />}>
        <Route path="/place/area1" element={<Area1 />} />
        <Route path="/place/area2" element={<Area2 />} />
    </Route>
  )
);

(二)、配置式映射关系

const router = createBrowserRouter([
  {
    path: "/",
    element: <Root />,
    children: [
      {
        path: "child1",
        element: <Child1 />,
      },
      {
        path: "child2",
        element: <Child2 />,
      },
    ],
  },
  {
    element: <AuthLayout />,
    children: [
      {
        path: "login",
        element: <Login />,
        loader: redirectIfUser,
      },
      {
        path: "logout",
        action: logoutUser,
      },
    ],
  },
]);

三、嵌套路由

配置嵌套路由关系:

(一)、组件式

// Configure nested routes with JSX
createBrowserRouter(
  createRoutesFromElements(
    <Route path="/" element={<Root />}>
      <Route path="contact" element={<Contact />} />
      <Route
        path="dashboard"
        element={<Dashboard />}
        loader={({ request }) =>
          fetch("/api/dashboard.json", {
            signal: request.signal,
          })
        }
      />
      <Route element={<AuthLayout />}>
        <Route
          path="login"
          element={<Login />}
          loader={redirectIfUser}
        />
        <Route path="logout" />
      </Route>
    </Route>
  )
);

(二)、配置式

createBrowserRouter([
  {
    path: "/",
    element: <Root />,
    children: [
      {
        path: "contact",
        element: <Contact />,
      },
      {
        path: "dashboard",
        element: <Dashboard />,
        loader: ({ request }) =>
          fetch("/api/dashboard.json", {
            signal: request.signal,
          }),
      },
      {
        element: <AuthLayout />,
        children: [
          {
            path: "login",
            element: <Login />,
            loader: redirectIfUser,
          },
          {
            path: "logout",
            action: logoutUser,
          },
        ],
      },
    ],
  },
]);

【注】在父路由组件中配置Outlet进行决定子路由组件渲染在父路由组件的哪个位置

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

export default function Root() {
  return (
    <>
      {/* all the other elements */}
      <div id="detail">
        <Outlet />
      </div>
    </>
  );
}

传参

params传参

<Route path="projects/:projectId/tasks/:taskId" />
function Task() {
  // returned from `useParams`
  const params = useParams();
  params.projectId; // abc
  params.taskId; // 3
}
function Random() {
  const match = useMatch("/projects/:projectId/tasks/3");
  match.params.projectId; // abc
  match.params.taskId; // 3
}

query传参

const [searchParams] = useSearchParams()
console.log('searchParams', Object.fromEntries(searchParams))

跳转

组件跳转

<NavLink /><Link />多了isActive 、isPending参数来表示当前路由是否是激活状态。

<NavLink
  style={({ isActive, isPending }) => {
    return {
      color: isActive ? "red" : "inherit",
    };
  }}
  className={({ isActive, isPending }) => {
    return isActive ? "active" : isPending ? "pending" : "";
  }}
/>
<Link
  style={({ isActive, isPending }) => {
    return {
      color: isActive ? "red" : "inherit",
    };
  }}
  className={({ isActive, isPending }) => {
    return isActive ? "active" : isPending ? "pending" : "";
  }}
/>

编程式跳转

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

function useLogoutTimer() {
  const userIsInactive = useFakeInactiveUser();
  const navigate = useNavigate();

  useEffect(() => {
    if (userIsInactive) {
      fake.logout();
      navigate("/session-timed-out");
    }
  }, [userIsInactive]);
}

错误页面

const router = createBrowserRouter([
  {
    path: "/",
    element: <div>Hello world!</div>,
    errorElement: <ErrorPage />,
  },
]);
// 查看错误信息
import { useRouteError } from "react-router-dom";

export default function ErrorPage() {
  const error = useRouteError();
  console.error(error);

  return (
    <div id="error-page">
      <h1>Oops!</h1>
      <p>Sorry, an unexpected error has occurred.</p>
      <p>
        <i>{error.statusText || error.message}</i>
      </p>
    </div>