React-Router

简介: React-Router

1. 什么是路由?

  • 路由维护了URL地址和组件的映射关系, 通过这个映射关系, 我们就可以根据不同的URL地址,去渲染不同的组件
    2.如何在React中使用路由
  • 安装react-router
    npm install react-router-dom
  • 通过指定监听模式
  • 通过Link修改路由URL地址
  • 通过Route匹配路由地址
    官网文档地址: https://reactrouter.com/web/guides/quick-start
    2..BrowserRouter和HashRouter作用:
    指定路由的监听模式 history模式 / hash模式
    http://www.baidu.com/home    history模式
    http://www.baidu.com/#/home  hash模式
    3.Link作用
    用于修改URL的资源地址
    4.Route作用:
  • 用于维护URL和组件的关系
  • Route是一个占用组件, 将来它会根据匹配到的资源地址渲染对应的组件
    需求: 界面上有两个按钮, 点击不同按钮显示不同组件

import React from 'react';
import Home from './components/Home'
import About from './components/About'
//导入需要使用的组件
import {BrowserRouter, HashRouter, Link, Route} from 'react-router-dom';
class App extends React.PureComponent{
    constructor(props){
        super(props); 
}
    render(){
        return (
            <div>
                <HashRouter>
                    <Link to={'/home'}>Home</Link>
                    <Link to={'/about'}>About</Link>
                    <Route path={'/home'} component={Home}/>
                    <Route path={'/about'} component={About}/>
                </HashRouter>
            </div>
        )
    }
}
export default App;
2.React路由注意点
2.1 react-router-dom和react-router-native
  • react-router4之前, 所有路由代码都是统一放到react-router中管理的
  • react-router4开始, 拆分为了两个包react-router-domreact-router-native
  • react-router-dom 在浏览器中使用路由
  • react-router-native 在原生应用中使用路由
2.2 BrowserRouter和HashRouter

-BrowserRouter history模式使用的是H5的特性, 所以兼容性会比HashRouterhash模式差一些

  • 在企业开发中如果不需要兼容低级版本浏览器, 建议使用BrowserRouter,如果需要兼容低级版本浏览器, 那么只能使用HashRouter
  • 论是Link还是Route都只能放到BrowserRouterHashRouter中才有效

class App extends React.PureComponent{
    render(){
        return (
            <div>
                {/*设置监听模式*/}
                <BrowserRouter>
                    {/*修改路由地址*/}
                    <Link to={'/home'}>Home</Link>
                    <Link to={'/about'}>About</Link>
                    {/*维护URL和组件关系*/}
                    <Route path={'/home'} component={Home}/>
                    <Route path={'/about'} component={About}/>
                </BrowserRouter>
            </div>
        )
    }
}
export default App;
2.3 Route注意点
  • 默认情况下Route在匹配资源地址时, 是模糊匹配
  • 如果必须和资源地址一模一样才匹配, 那么需要添加exact属性, 开启精准匹配
2.4 Link注意点
  • 默认情况下Link会渲染成一个a标签, 如果想渲染成其他的元素, 可以通过手动路由跳转来实现
2.5.NavLink注意点
  • 默认情况下NavLink在匹配资源地址时, 是模糊匹配,如果必须和资源地址一模一样才匹配, 那么需要添加exact属性, 开启精准匹配
模糊匹配

NavLink在匹配路由的时候, 是利用当前资源地址从左至右的和path中的地址进行匹配的

只要当前资源地址从左至右完整的包含了path中的地址那么就认为匹配

当前资源地址 : /home/about

to中的地址: /home

to中的地址: /home/about

  • NavLink在匹配路由的时候, 是利用当前资源地址从左至右的和path中的地址进行匹配的,只要当前资源地址从左至右完整的包含了path中的地址那么就认为匹配
  • NavLink有一个Link没有的属性activeStyle

<NavLink exact to={'/home'} activeStyle={{color:'red'}}>Home</NavLink>
<NavLink exact to={'/home/about'} activeStyle={{color:'red'}}>About</NavLink>
//当前资源地址 : /home/about,to中的地址: /home&& /home/about,因为是模糊匹配

3. Switch

默认情况下路由会从上至下匹配所有的Route, 只要匹配都会显示,但是在企业开发中大部分情况下, 我们希望的是一旦有一个匹配到了后续就不要再匹配了

此时我们就可以通过Switch来实现

import React from 'react';
import Home from './components/Home'
import About from './components/About'
import Other from './components/Other'
import {BrowserRouter, Link, Route, Switch} from 'react-router-dom';
class App extends React.PureComponent{
    render(){
        return (
            <div>
                <BrowserRouter>
                    <Link to={'/home'}>Home</Link>
                    <Link to={'/about'}>About</Link>
                    <Switch>
                        <Route exact path={'/home'} component={Home}/>
                        <Route exact path={'/about'} component={About}/>
                        {/*如果Route没有指定path, 那么表示这个Route和所有的资源地址都匹配*/}
                        <Route component={Other}/>
                    </Switch>
                </BrowserRouter>
            </div>
        )
    }
}
export default App;


35.png

35.png


image.png

Redirect

Redirect:资源重定向, 也就是可以在访问某个资源地址的时候重定向到另外一个资源地址

例如: 访问/user 重定向到 /login

注意点:如果要使用嵌套路由, 那么外层路由不能添加精准匹配exact

import React from 'react';
import {Redirect} from 'react-router-dom';
class User extends React.PureComponent{
    constructor(props){
        super(props);
        this.state = {
            isLogin: false
        }
    }
    render(){
        let user = (
            <div>
                <h1>用户界面</h1>
                <p>用户名: yiya_xiaoshan</p>
                <p>密码: www.baidu.com</p>
            </div>
        );
        let login = <Redirect to={'/login'}/>
        return this.state.isLogin ? user : login;
    }
}
export default User;

嵌套路由

路由里面又有路由, 就称之为嵌套路由

//app.js
import React from 'react';
import Home from './components/Home'
import About from './components/About'
import Other from './components/Other'
import User from './components/User'
import Login from './components/Login'
import Discover from './components/Discover'
import {BrowserRouter, NavLink, Route, Switch} from 'react-router-dom';
class App extends React.PureComponent{
    render(){
        return (
            <div>
                <BrowserRouter>
                    <NavLink to={'/home'} activeStyle={{color:'red'}}>Home</NavLink>
                    <NavLink to={'/about'} activeStyle={{color:'red'}}>About</NavLink>
                    <NavLink to={'/user'} activeStyle={{color:'red'}}>User</NavLink>
                    <NavLink to={'/discover'} activeStyle={{color:'red'}}>广场</NavLink>
                    <Switch>
                        <Route exact path={'/home'} component={Home}/>
                        <Route exact path={'/about'} component={About}/>
                        <Route exact path={'/user'} component={User}/>
                        <Route exact path={'/login'} component={Login}/>
                        <Route path={'/discover'} component={Discover}/>
                        <Route component={Other}/>
                    </Switch>
                </BrowserRouter>
            </div>
        )
    }
}
export default App;

//discover界面
import React from 'react';
import {NavLink, Switch, Route} from "react-router-dom";
function Hot() {
    return (
        <div>推荐</div>
    )
}
function TopList() {
    return (
        <div>排行榜</div>
    )
}
function PlayList() {
    return (
        <div>歌单</div>
    )
}
class Discover extends React.PureComponent{
    render(){
        return (
            /*
            注意点: 由于当前组件是在BrowserRouter or HashRouter中显示的
                   所以在当前组件中不用使用BrowserRouter or HashRouter来包裹NavLink/Switch/Route
            * */
            <div>
                <NavLink exact to={'/discover'} activeStyle={{color:'red'}}>推荐</NavLink>
                <NavLink exact to={'/discover/toplist'} activeStyle={{color:'red'}}>排行榜</NavLink>
                <NavLink exact to={'/discover/playlist'} activeStyle={{color:'red'}}>歌单</NavLink>
                <Switch>
                    <Route exact path={'/discover'} component={Hot}/>
                    <Route exact path={'/discover/toplist'} component={TopList}/>
                    <Route exact path={'/discover/playlist'} component={PlayList}/>
                </Switch>
            </div>
        )
    }
}
export default Discover;

通过JavaScript手动路由

1.手动路由跳转:

不通过Link/NavLink来设置资源地址, 而是通过JS来设置资源地址

  • Hash模式
    如果是Hash模式, 那么只需要通过JS设置Hash值即可
    window.location.hash = '/discover/playlist';
    如果一个组件是通过路由创建出来的, 那么系统就会自动传递一个history给我们
  • history模式
    我们只需要拿到这个history对象, 调用这个对象的push方法, 通过push方法修改资源地址即可
    console.log(this.props.history);

btnClick(){
        //hash模式
        window.location.hash = '/discover/playlist';
        // history 模式
        console.log(this.props.history);
        this.props.history.push('/discover/playlist');
    }
1.手动路由跳转注意点:
  • 只有通过路由创建出来的组件才有history对象, 所以不能在根组件中使用手动路由跳转
  • 如果想在根组件中使用手动路由跳转, 那么需要借助一个withRouter高阶组件
  • 如果一个组件是通过路由创建的, 那么系统就会自动给这个组件传递一个history对象
    但是如果一个组件不是通过路由创建的, 那么系统就不会给这个组件传递一个history对象
  • 如果现在非路由创建出来的组件中使用history对象, 那么可以借助withRouter高阶组件
  • 只要把一个组件传递给withRouter方法, 那么这个方法就会通过路由将传入的组件创建出来
  • 注意点: 如果一个组件要使用路由创建, 那么这个组件必须包裹在BrowserRouter, HashRouter

import React from 'react';
import Home from './components/Home'
import About from './components/About'
import Other from './components/Other'
import User from './components/User'
import Login from './components/Login'
import Discover from './components/Discover'
import {BrowserRouter, HashRouter, NavLink, Route, Switch, withRouter} from 'react-router-dom';
class App extends React.PureComponent{
    render(){
        return (
            <div>
                    <NavLink to={'/home'} activeStyle={{color:'red'}}>Home</NavLink>
                    <NavLink to={'/about'} activeStyle={{color:'red'}}>About</NavLink>
                    <NavLink to={'/user'} activeStyle={{color:'red'}}>User</NavLink>
                    <NavLink to={'/discover'} activeStyle={{color:'red'}}>广场</NavLink>
                    <button onClick={()=>{this.btnClick()}}>广场</button>
                    <Switch>
                        <Route exact path={'/home'} component={Home}/>
                        <Route exact path={'/about'} component={About}/>
                        <Route exact path={'/user'} component={User}/>
                        <Route exact path={'/login'} component={Login}/>
                        <Route path={'/discover'} component={Discover}/>
                        <Route component={Other}/>
                    </Switch>
            </div>
        )
    }
    btnClick(){
        // window.location.hash = '/discover';
        //Cannot read property 'push' of undefined
        this.props.history.push('/discover');
    }
}
export default withRouter(App);

5.路由参数传递

1.路由参数传递


目录
相关文章
|
4月前
|
移动开发 资源调度 前端开发
React Router V6 useRoutes的使用
【8月更文挑战第29天】 React Router V6 useRoutes的使用
187 3
|
4月前
|
前端开发 JavaScript UED
什么是 React Router?
【8月更文挑战第31天】
29 0
|
前端开发
react总结之react-router-dom
react总结之react-router-dom
|
7月前
|
前端开发 JavaScript API
React Router v6 完全指南(下)
React Router v6 完全指南(下)
262 0
|
7月前
|
存储 资源调度 前端开发
React Router v6 完全指南(上)
React Router v6 完全指南(上)
390 0
|
缓存 移动开发 前端开发
【React】react-router 路由详解
【React】react-router 路由详解
343 1
【React】react-router 路由详解
|
前端开发
【react 中router v6 与 v5 区别】
【react 中router v6 与 v5 区别】
|
前端开发 网络架构
【React】React-router路由
React-router路由
112 0
|
前端开发 JavaScript API
react-router与react-router-dom区别
React 是一个流行的JavaScript库,用于构建用户界面,而`React Router`是为 React 应用程序提供路由功能的常用解决方案之一。 React Router是一个用于构建路由的库,它提供了核心的API,例如`Router`、`Route`和`Switch`。它允许开发者将不同的组件与特定的URL路径相关联,并根据用户的导航选择加载相应的组件。React Router通过管理URL的变化,帮助我们在单页应用程序中实现导航和路由。 然而,React Router本身并没有提供直接操作DOM进行路由跳转的API。这就是`React Router DOM`的出现背景。
321 0