关于React-Router6 (React 路由)

一、概要

(1)每个单页应用其实是一系列的 JS 文件,当用户请求网站时,网站返回一整个(或一系列)的 js 文件和 HTML,而当用户在某个页面内点击时,你需要告诉浏览器怎么加载另一个页面地址。单页应用中通常只有一个 index.html 文件的,所以浏览器自带的 <a> 链接 tag 并不能用来做单页应用的跳转,因此你需要一个在 React 中的路由实现。

然而 React 框架本身是不带路由功能的,因此如果你需要实现路由功能让用户可以在多个单页应用中跳转的话,就需要使用 React-Router。

 

(2)全局路由有常用两种路由模式可选:HashRouter 和 BrowserRouter

  • HashRouter:URL中采用的是hash(#)部分去创建路由,类似www.example.com/#/

  • BrowserRouter:URL采用真实的URL资源 这里我们采用BrowserRouter来创建路由

1.1、route的功能

1.2、路由通配符

/groups

/groups/admin

/users/:id

/users/:id/messages

/files/* /files/:id/*

 

二、使用

 2.1、安装 React-Router

npm install react-router-dom(没有指定版本,默认最新版)

2.2、创建组件

在 src 文件夹里面创建一个 component / index / index.jsx 组件,在 index 文件夹里再创建3个孙组件( index / p1.jsx、index / p2.jsx、index / p3.jsx)

在component文件夹下,再创建一个user文件夹,里面放3个孙组件(user / u1.jsx、user / u2.jsx、user / u3.jsx)

以上,创建那么文件夹和文件的作用是为了方便测试而已,要使用的时候还是按照自己的实际需要好!!!

2.3、孙组件内容

p1.jsx代码如下:

import React from "react";

export default class Pone extends React.Component{
    render(){
        return(
            <>
                <h1>p1</h1>
            </>
        )
    }
}

其他几个孙组件的内容大致一样就不展示了!

2.4、子组件内容

index.jsx 代码如下:

import React from "react";
import { NavLink,Outlet } from "react-router-dom";

export default class Index extends React.Component{
    render(){
        return(
            <>
                {/* 跳转页面到某个路由 */}
                <NavLink to="p1">p1</NavLink>
                <NavLink to="p2">p2</NavLink>
                <NavLink to="p3">p3</NavLink>
                <hr />
                {/* 这个也是占位符,把子路由的内容放在这里 */}
                <Outlet></Outlet>
            </>
        )
    }
}

其他几个子组件的内容大致一样就不展示了!

2.5、父组件内容

App.js 代码如下:

import route from "./route";
import { NavLink,useRoutes } from "react-router-dom";
import './index.css'

function App() {
  // 占位符,相当于把路由放在这个地方
  const element = useRoutes(route)
  return (
    <div className="App">
      <NavLink to="/home">主页</NavLink>
      <NavLink to="/user">用户</NavLink>
      <hr />
      {
        element
      }
    </div>
  );
}

export default App;

2.6、创建路由表

在 src 文件夹下创建一个 route 文件夹下,在route文件夹下创建一个 index.js

具体代码如下:

// 组件
import Index from "../component/index";
import Pone from "../component/index/p1";
import Ptwo from "../component/index/p2";
import Pthere from "../component/index/p3";

import User from "../component/user/user";
import Uone from "../component/user/u1";
import Utwo from "../component/user/u2";
import Uthere from "../component/user/u3";
// 跳转页面的
import { Navigate } from "react-router-dom";

// 默认导出
// eslint-disable-next-line import/no-anonymous-default-export
export default [
    // 路由规则
    {
        path:"/home",
        element: <Index></Index>,
        // 一级路由的子路由,即嵌套路由
        children: [
            {
                path: "p1",
                element: <Pone></Pone>
            },
            {
                path: "p2",
                element: <Ptwo></Ptwo>
            },
            {
                path: "p3",
                element: <Pthere></Pthere>
            },
            {
                path:"",
                element: <Navigate to="/home/p1"></Navigate>
            }
        ]
    },
    {
        path:"/",
        element: <Navigate to="/home"></Navigate> // Navigate:页面的跳转;此规则用于重定向
    },
    {
        path:"/user",
        element: <User></User>,
        children:[
            {
                path: "u1",
                element: <Uone></Uone>
            },
            {
                path: "u2",
                element: <Utwo></Utwo>
            },
            {
                path: "u3",
                element: <Uthere></Uthere>
            },
            {
                path:"",
                element: <Navigate to="/user/u1"></Navigate>
            }
        ]
    }

]

2.7、入口文件内容(src/index.js)

 import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { BrowserRouter } from 'react-router-dom';   

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  // React.StrictMode:检测代码是否规范
  // <React.StrictMode> 
    <BrowserRouter>
      <App />
    </BrowserRouter>
  // </React.StrictMode>
  
);

2.8、运行结果

三、跳转页面的方法

3.1、在路由表导入“ 注册 ” 的组件

// 该文件为路由表,定义一些路由信息
import { Navigate } from 'react-router-dom'
import React,{lazy} from 'react'

// 动态加载组件
const Login = lazy(()=>import('../view/Login'))
const Register = lazy(()=>import('../view/Register'))

// 解决懒加载报错问题
const fun = (Com)=>(<React.Suspense fallback={'loading...'}>
        {Com}
    </React.Suspense>
)

export default [
    {
        path: '/Login',
        element: fun(<Login/>)
    },
    {
        path: '/Register',
        element: fun(<Register/>)
    },
    {
        path: '/', 
        element: <Navigate to="/Login"/>
    }
]

3.2、使用useNavigate从登录页面跳转到注册页面

导入:

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

实现:

const navigate = useNavigate();
navigate('/path');

报错:

A component suspended while responding to synchronous input. This will cause the UI to be replaced with a loading indicator. To fix, updates that suspend should be wrapped with startTransition.

原因:

在响应同步输入时,某个组件发生了挂起(suspended)的情况,导致用户界面被替换为加载指示器。这通常是由于在渲染中,某个异步操作(如数据获取、网络请求等)耗时较长,导致组件挂起,从而影响了用户体验。

解决:

为了解决这个问题,React 18 引入了一个新的 API startTransition,用于告知 React 暂停当前渲染,直到异步操作完成后再继续渲染。你可以在组件中使用startTransition包装异步更新,以避免组件挂起的情况。

具体代码实现:

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

// 跳转页面
  const navigate = useNavigate();
  // 跳转到注册页面
  function goRegister(){
    // startTransition,用于告知 React 暂停当前渲染,直到异步操作完成后再继续渲染。
    startTransition(() => {
        // 包装异步更新,以避免组件挂起的情况。
        navigate("/Register"); // 跳转到这个路由下的页面
    });
  }  

 

posted @ 2023-03-01 12:55  __fairy  阅读(585)  评论(0编辑  收藏  举报