Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

route V6 总结 #75

Open
xiaochengzi6 opened this issue May 17, 2023 · 0 comments
Open

route V6 总结 #75

xiaochengzi6 opened this issue May 17, 2023 · 0 comments
Labels
React React 库

Comments

@xiaochengzi6
Copy link
Owner

react-router 6.11.1

React-router

react 有两种模式一种使用 数据路由 另外一种使用组件式路由

具体要配合 react-router 库去看

一、<Routers> 组件代替原有<Switch>,所有子路由都用基础的Router children来表示

<Routers location>
  <Route path="/top" element={<Top />}/>
  <Route path="/content" childes>
</Routers>

<Route> 可以用匹配路由渲染组件的

<Route 
 path="/top"
 loader={({params}) => { console.log(params)}}
 action={({params}) => {}}
 element={<Top />}>
  1. path: 要与 URL 匹配的路径模式,以确定此路由是否匹配 URL、 link href 或表单操作

  2. loader: 在路由呈现之前事前可以进行数据请求, 使用 useLoaderData hook 取到值

例如:

function Root () {
  const router = createBrowserRouter({
    path: '/',
    element: <Element />,
    loader: () => {
      // 这里进行数据请求
      return featchData() 
    }
  })
}

function Element() {
  // 取到 data 数据
  const data = useLoaderData() 
  
  // ...
}
  1. action:

  2. errorElement/errorBoundary: 当路由在渲染时抛出异常,在 loader 或 action 中,这个 React 元素/组件将会代替正常的 element / Component 进行渲染。

<Route
  path="/for-sale"
  element={<Properties />}
  // 如果发生错误
  // 这里会显示 ErrorBoundary 组件
  errorElement={<ErrorBoundary />}
/>
  1. layz :为了使你的应用程序包小并支持你的路由的代码分割,每个路由都可以提供一个异步函数,该函数解析你的路由定义中不匹配路由的部分 ( loader 、 action 、 Component / element 、 ErrorBoundary / errorElement 等)。

这里理解不太到位

let routes = createRoutesFromElements(
  <Route path="/" element={<Layout />}>
    <Route path="a" lazy={() => import("./a")} />
    <Route path="b" lazy={() => import("./b")} />
  </Route>
);

每个 lazy 函数通常会返回一个动态导入的结果。

参考:https://reactrouter.com/en/main/route/lazy

{
      path: "messages",
      async lazy() {
        let { messagesLoader, Messages } = await import(
          "./pages/Dashboard"
        );

        // 这里提供 loader 和 Component 数据
        return {
          loader: messagesLoader,
          Component: Messages,
        };
      },
    },
  1. handle 任何应用程序特定的数据,主要配合 useMatches 使用

使用 useMatches 钩子能够获取以下数据类型

{
  id,
  pathname,
  data,
  params,
  // 获取 handle 函数
  handle
}

二、使用 <Outlet> 来渲染它们的子路由元素。这样可以在渲染子路由时显示嵌套的 UI。如果父路由完全匹配,则会渲染子索引路由,如果没有索引路由,则不会渲染任何内容。

function Dashboard() {
  return (
    <div>
      <h1>Dashboard</h1>
      // 在这里使用
      <Outlet />
    </div>
  );
}

function App() {
  return (
    <Routes>
    // 父组件
      <Route path="/" element={<Dashboard />}>
      // 子组件
        <Route
          path="messages"
          element={<DashboardMessages />}
        />
        <Route path="tasks" element={<DashboardTasks />} />
      </Route>
    </Routes>
  );
}

三、useNavigateNavigate

使用 useNavigate 可以返回一个函数,以函数的形式导航

// useNavigate 接收的参数
interface NavigateFunction {
  (
    to: To,
    options?: {
      replace?: boolean;
      state?: any;
      relative?: RelativeRoutingType;
    }
  ): void;
  (delta: number): void;
}
  1. 要么传递一个 To 值(与 相同的类型),带有可选的第二个 { replace, state } 参数,要么
  2. 传递您想要在历史堆栈中前进的增量。例如, navigate(-1) 等同于点击后退按钮。
function Top() {
  const navigate = useNavigate()

  useEffect(() => {
    navigate("/top")
  })

  return(
    <div>   </div>
  )
}

四、<Link> 让用户通过点击跳转到另一个页面

参考:https://baimingxuan.github.io/react-router6-doc/components/link.html#relative

import * as React from "react";
import { Link } from "react-router-dom";

function UsersIndexPage({ users }) {
  return (
    <div>
      <h1>Users</h1>
      <ul>
        {users.map((user) => (
          <li key={user.id}>
            // 跳转
            <Link to={user.id}>{user.name}</Link>
          </li>
        ))}
      </ul>
    </div>
  );
}

五、<Await>用于呈现具有自动错误处理的延迟值(是一个延迟的值)

通常配合 React.Suspense 使用,它是在子组件未加载完时选它提供的组件,具体:https://zh-hans.react.dev/reference/react/Suspense#suspense

参考:https://baimingxuan.github.io/react-router6-doc/components/await.html#await

function Book() {
  const { book, reviews } = useLoaderData();
  return (
    <div>
      <h1>{book.title}</h1>
      <p>{book.description}</p>
      // 如果子组件未加载就先渲染 fallback 提供的组件
      <React.Suspense fallback={<ReviewsSkeleton />}>
      // 延迟的值
        <Await
          // 接受从延迟、加载器 值返回的 promise,以便解决和渲染。
          resolve={reviews}
          // 当Promise被拒绝时,错误元素将呈现而不是子元素
          errorElement={
            <div>Could not load reviews 😬</div>
          }
          // 可以是React元素或函数。
          //   是React函数,useAsyncValue ()将提供数据:
          children={(resolvedReviews) => (
            <Reviews items={resolvedReviews} />
          )}
        />
      </React.Suspense>
    </div>
  );
}

hook

  1. useActionData此钩子提供了上一次导航的 action 结果的返回值,如果没有提交,则为 undefined 。

  2. useAsyncError 从最近的 [await] 组件返回拒绝值。

function ErrorElement() {
  const error = useAsyncError();
  return (
    <p>Uh Oh, something went wrong! {error.message}</p>
  );
}

<Await
  resolve={promiseThatRejects}
  errorElement={<ErrorElement />}
/>;
  1. useAsyncValue 从最近的 祖先组件返回已解析的数据。
function Child() {
  // 这里拿到值
  const asyncValue = useAsyncValue()
  
}
<Await> 
  <Child />
</Await>
  1. useBeforeUnload是 window.onbeforeunload 的辅助工具 在用户离开页面之前,将重要的应用程序状态保存在页面上

  2. useLocation返回当前的location (opens new window)对象。如果您想在当前位置更改时执行一些副作用,这可能会很有用。

  3. useMatch 传入一个 url 与当前路由去匹配,如果匹配上就返回一个匹配的信息,否则返回null

场景题

  1. 重定向
<Route 
 path='/home'
 loader={async () => {
   const result = awit featch()
   if(!result) {
     redirect('/login')
   }
 }}
 >

Redirect 组件被移除,取而代之的是Navigate 组件

<Navigate>重定向 当 <Navigate replace to="/error-page"> 可以替换当前页面,也就是不会改变历史消息

// 条件性重定向
<Route 
 path="/login"
 element={login ? <Login /> : <Navigate to="/navigate" />}
 >
function Top (){
  const navigate = useNavigate()

  return (
    <div>
      //  重定向
       <button onClick={() => navigate('/data')}>
    </div>
  )
}

参考:https://juejin.cn/post/7114889463825694727

@xiaochengzi6 xiaochengzi6 added the React React 库 label May 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
React React 库
Projects
None yet
Development

No branches or pull requests

1 participant