React-router

2023-12-14 20:54:43

目录

一、前端路由(改变URL,页面不进行整体刷新的两种方式)

1、URL 的hash

2、HTML5 的History

二、react-router

1、router 的两种方式

2、路由的示例

3、Navigate

a、默认展示登录按钮,点击登录按钮后跳转到home 页面

b、Navigate 可以用来重定向

4、NotFound 页面

5、路由的嵌套

6、编程式路由跳转

a、函数组件的路由跳转

b、类组件的路由跳转

7、路由传参

a、动态路由传参

?b、拼接查询字符串

8、配置路由信息


一、前端路由(改变URL,页面不进行整体刷新的两种方式)

前端路由的核心:改变URL时,页面不进行整体的刷新

1、URL 的hash

  • URL 的hash 也就是锚点(#),本质上是改变window.location 的href 属性
  • 可以通过直接赋值location.hash 来改变href ,但是页面不发生刷新
  • hash 的优势是兼容性更好,在老版IE中都可以运行,但是缺陷是有一个#,显得不像一个真实的路径

2、HTML5 的History

history 接口是HTML5 新增的,它有六种模式改变URL 而不刷新页面

  1. replaceState:替换原来的路径
  2. pushState:使用新的路径
  3. popState:路径的回退
  4. go:向前或向后改变路径
  5. forward:向前改变路径
  6. back:向后改变路径

二、react-router

npm install react-router-dom

默认是pushState 操作

1、router 的两种方式

  • react-router 最主要的API 是提供的一些组件
  • BrowserRouter 使用的是history 模式
  • HashRouter 使用的是hash 模式
import { StrictMode } from "react"
import ReactDOM from "react-dom/client"
import { HashRouter } from "react-router-dom"
import App from "./App"
const root = ReactDOM.createRoot(document.querySelector("#root"))
root.render(
    <StrictMode>
        <HashRouter>
            <App/>
        </HashRouter>
    </StrictMode>
)

2、路由的示例

imort { Link, NavLink, Route, Routes } from 'react-router-dom'
<Link to="/home">home</Link>
<Link to="/about">about</Link>
<Routes>
    <Route path="/home" element={ <Home/> } />
    <Route path="/about" element={ <About/> } />
</Routes>

3、Navigate

a、默认展示登录按钮,点击登录按钮后跳转到home 页面
import { Navigate } from 'react-router-dom'
export class App extends PureComponent {
    constructor(props) {
        super(props)
        this.state = {
            isLogin: false
        }
    }
    login() {
        this.setState({ isLogin: true })
    }
    render() {
        const { isLogin } = this.state
        return (
            <div>
                { !isLogin ? <button onClick={ e => this.login() }>登录</button> : <Navigate to="/home" />}
            </div>
        )
    }
}
b、Navigate 可以用来重定向
<Route path="/" element={<Navigate to="/home" />} />
<Route path="/home" element={ <Home/> } />
<Route path="/about" element={ <About/> } />

4、NotFound 页面

<Route path="/" element={<Navigate to="/home" />} />
<Route path="/home" element={ <Home/> } />
<Route path="/about" element={ <About/> } />
<Route path="*" element={ <NotFound/> } />

5、路由的嵌套

<Route path="/" element={<Navigate to="/home" />} />
<Route path="/home" element={ <Home/> } >
    <Route path="/home" element={ <Navigate to="/home/recommend"/> } />
    <Route path="/home/recommend" element={<HomeRecommend/> } />
    <Route path="/home/ranking" element={<HomeRanking/>} />
</Route>
<Route path="/about" element={ <About/> } />
<Route path="*" element={ <NotFound/> } />


<Link to="/home/recommend">推荐</Link>
<Link to="/home/ranking">推荐</Link>
// 占位的组件
<Outlet/>

6、编程式路由跳转

a、函数组件的路由跳转
import { useNavigate } from "react-router-dom"
export function App(props) {
    const navigate = useNavigate()
    function navigateTo(path) {
        navigate(path)
    }
    return {
        <div>
            <button onClick={ e => navigateTo("/category") }>分类</button>
            <button onClick={ e => navigateTo("/order") }>订单</button>
        </div>
    }
}
export default App
b、类组件的路由跳转
export class Home extends PureComponent {
    navigateTo(path) {
        const { navigate } = this.props.router
        navigate(path)
    }
    render() {
        return (
            <div>
                <Link to="/home/recommend">推荐</Link>
                <Link to="/home/ranking">排行榜</Link>
                <button onClick={ e => this.navigateTo("/home/songmenu") }>歌单</button>
                <!-- 占位的组件 -->
                <Outlet/>
            </div>
        )
    }
}
// 高阶函数:函数
function withRouter(WrapperComponent) {
    return function(props) {
        const navigate = useNavigate()
        const router = { navigate }
        return <WrapperComponent {...props} router={router} />
    }
}
export default withRouter(Home)

7、路由传参

a、动态路由传参
// with_router.js
import { useNavigate, usePrams } from "react-router-dom"
function withRouter(WrapperComponent) {
    return function(props) {
        const navigate = useNavigate()
        const params = useParams()
        const router = { navigate, params } 
        return <WrapperComponent {...props} router={router} />
    }
}
export default withRouter
<Route path='/detail/:id' element={<Detail/>} />
import { widthRouter } from "../hoc"
export class HomeSongMenu extends PureComponent {
    constructor(props) {
        super(props)
        this.state = {
            songMenus: [
                { id: 1, name: a },
                { id: 2, name: b },
                { id: 3, name: c },
            ]
        }
    }
    NavigateToDetail(id) {
        const { navigate } = this.props.router
        navigate("/detail/" + id)
    }
    render() {
        const { songMenus} = this.state
        return (
            <div>    
                <ul>
                    {
                        songMenus.map(item => {
                            return <li key={item.id} onClick={e=>this.NavigateToDetail(item.id)}>{item.name}</li>
                        })
                    }
                </ul>
            </div>
        )    
    }
}
export default withRouter(HomeSongMenu)
import { widthRouter } from '../hoc'
export class Detail extends PureComponent {
    render() {
        const { router } = this.props
        const { params } = router
        return (
            <div>
                <h2>id: { params.id }</h2>
            </div>
        )
    }
}
export default widthRouter(Detail)
?b、拼接查询字符串
<Link to="/user?name=why&age=18">用户</Link>
<Route path="/user" element={<User/>} />
// with_router.js
import { useNavigate, usePrams, useSearchParams } from "react-router-dom"
function withRouter(WrapperComponent) {
    return function(props) {
        const navigate = useNavigate()
        const params = useParams()
        const [ searchParams, setSearchParams ] = useSearchParams()
        const query = Object.fromEntries(searchParams)
        const router = { navigate, params, query } 
        return <WrapperComponent {...props} router={router} />
    }
}
export default withRouter
export class User extends PureComponent {
    render() {
        const { router } = this.props
        const { query } = router
        return {
            <div>
                <h2>{ query.name } - { query.age }</h2>    
            </div>
        }
    }
}
export default withRouter(User)

8、配置路由信息

// router/index.js
import { Navigate } from "react-router-dom"
const routes = [
    {
        path: "/", 
        element: <Navigate to="/home" />,
    },
    { 
        path: "/", 
        element: <Home/>,
        children: {
            { path: "/home", element: <Navigate to="/home/recommend" /> },
            { path: "/home/recommend", element: <HomeRecommend/> },
            { path: "/home/ranking", element: <HomeRanking/> },
        }
        
    },
    {
        path: "/detail/:id", 
        element: <Detail/>,
    },
    {
        path: "*", 
        element: <NotFound/>,
    }
]
export default routes

// App.jsx
import routes from @/router/index.js
<div>
    { useRoutes(routes) }
</div>

9、路由懒加载

// router/index.js
import React from 'react'
import { Navigate } from "react-router-dom"
const About = React.lazy(() => import("../pages/About"))
const Login = React.lazy(() => import("../pages/Login"))
const routes = [
    {
        path: "/", 
        element: <Navigate to="/home" />,
    },
    { 
        path: "/", 
        element: <Home/>,
        children: {
            { path: "/home", element: <Navigate to="/home/recommend" /> },
            { path: "/home/recommend", element: <HomeRecommend/> },
            { path: "/home/ranking", element: <HomeRanking/> },
        }
        
    },
    {
        path: "/detail/:id", 
        element: <Detail/>,
    },
    {
        path: "*", 
        element: <NotFound/>,
    }
]
export default routes

// src/index.js
import { Suspense } from 'react'
<Suspense fallback={<h3>loading...</h3>}>
    <App/>
</Suspense>

// App.jsx
import routes from @/router/index.js
<div>
    { useRoutes(routes) }
</div>

文章来源:https://blog.csdn.net/qq_50829019/article/details/134932881
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。