React-router 安装,配置,调用,嵌套,传参

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/FlowGuanEr/article/details/100018606

React Router 是完整的 React 路由解决方案。

React Router 保持 UI 与 URL 同步。它拥有简单的 API 与强大的功能例如代码缓冲加载、动态路由匹配、以及建立正确的位置过渡处理。你第一个念头想到的应该是 URL,而不是事后再想起。

路由的环境搭建和配置

使用一下命令安装 React 的路由。

react-router: 实现了路由的核心功能

react-router-dom: 基于 react-router,加入了在浏览器运行环境下的一些功能,例如:Link 组件,会渲染一个 a 标签,Link 组件源码 a 标签行; BrowserRouterHashRouter 组件,前者使用pushStatepopState 事件构建路由,后者使用window.location.hashhashchange 事件构建路由。

// react-router-dom 依赖于 react-router,安装它时会自动安装 react-router
npm i react-router-dom --save

路由的调用、渲染和封装

react-routervue-router 基本原理比较相似,都是通过控制网页 url 变化实现前端路由,在不刷新页面的基础上更新页面的内容,或者跳转页面。

一、React-router 配置和调用的简单示例

// App.js
import React from 'react';
// 从 react-router-dom 中导入配置路由需要的组件
import { BrowserRouter as Router, Route, Link } from "react-router-dom";

// 导入被路由的子组件
import About from './components/About'
import Topics from './components/Topics'

import './App.css';

// 配置路由并调用路由
function App() {
  return (
    <div className="App">
        <div>其他内容区域</div>
        <Router>
            <div>
                <ul>
                    <li>
                        <Link to="/about">About</Link>
                    </li>
                    <li>
                        <Link to="/topics">Topics</Link>
                    </li>
                </ul>

                <hr />

                <Route path="/about" component={About} />
                <Route path="/topics" component={Topics} />
            </div>
        </Router>
    </div>
  );
}

export default App;

注: 如果一个组件中需要配置或使用路由,建议将 BrowserRouter 作为其根组件。

在项目研发过程中,一般一个项目的根组件就是根路由,其上所有的路由都是在根路由的基础上衍生的子路由,由于react-router 本身的特点比较特殊,我们会将 <App> 组件渲染在根路由配置中,然后将 index.js 逻辑入口中的根组件渲染成根路由组件,以下是示例:

// 根路由配置文件 router.js
import React, { Component } from 'react';
import { BrowserRouter as Router} from 'react-router-dom';
import App from './App';

class Router extends Component {
  render() {
    return (
      <Router>
        <App />
      </Router>
    );
  }
}
export default Router;
// 逻辑入口 index.js
import React from 'react';
import ReactDOM from 'react-dom';
import Router from './router';

// 用 Router 组件代替 App 作为根组件
ReactDOM.render(<Router />, document.getElementById('root'));

嵌套路由和默认路由

一、 嵌套路由

嵌套路由是在当前被路由组件内部再配置路由并且在对应位置渲染即可。

比如在上面的示例中,<App> 组件中有两个被路由组件,分别是 <About /><Topics />,这相当于一级路由,如果 <About /> 组件中还有子路由 <A1 /> 组件和 <A2 /> 组件,那么可以进行如下配置:

// About.js
import React from 'react'
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import A1 from './A-1'
import A2 from './A-2'

class About extends React.Component {
    render() {
        return (
            <Router>
                <ul>
                    <li>
                        <Link to="/about/a1">a-module1</Link>
                    </li>
                    <li>
                        <Link to="/about/a2">a-module1</Link>
                    </li>
                </ul>

                <Route path="/about/a1" component={A1} />
                <Route path="/about/a2" component={A2} />
            </Router>
        );
    }
}
export default About;

二、默认路由

在上面的示例中,如果在菜单切换到 <About /> 组件时,需要展示 <A1 /> 组件,就要设置默认路由:

react-router 可以通过两种方式实现路由:

方式一

{/* 当路由切换到 /about 时,会自动渲染 A1 组件 */}
<Route path="/about" exact component={A1}></Route>
<Route path="/about/a1" component={A1} />
<Route path="/about/a2" component={A2} />

方式二

{/* 当路由切换到 /about 时,会自动重定向到 /about/a1 */}
<Redirect path="/about" to="/about/a1" />
<Route path="/about/a1" component={A1} />
<Route path="/about/a2" component={A2} />

<Redirect /> 组件会重定向 url

react-router 4.x 版本推出之后,路由配置不再有集中的配置。

路由参数的传递和接受

路由传参时单页面应用开发常见的需求。

一、在 url 中使用通配符直接传参

给一个需求,有一个博客列表菜单,点任意一篇,要在路由位置渲染对应的数据。

那么我们就需要在点击菜单时渲染路由组件并传参:

// Blog-list.js
import React from 'react'
import { BrowserRouter as Router, Route, Link, Redirect } from "react-router-dom";
import Blog from './Blog'

class BlogList extends React.Component {
    render() {
        return (
            <Router>
                <ul>
                    <li>
                        <Link to="/blog/1">博客1</Link>
                    </li>
                    <li>
                        <Link to="/blog/2">博客2</Link>
                    </li>
                    <li>
                        <Link to="/blog/3">博客3</Link>
                    </li>
                </ul>


                <Route path="/blog/:id" component={Blog} />
            </Router>
        );
    }
}
export default BlogList

<Blog /> 组件中获取参数

// Blog.js
import React from 'react'
class A1 extends React.Component {
    render() {
        // 接受参数列表
        const match = this.props.match;
        return <h1>
            {match.params.id} 
        </h1>;
    }
}
export default A1

这种调用和传参会在 url 中暴露参数。

二、使用 query 传参

<Link to={
    {
        pathname: '/about/a1',
        query: {
            id: 1,
            name: 'tom'
        }
    }
}>详情页</Link>

接收参数

import React from 'react'
class Detail extends React.Component {
    render() {
        // 接受 query 的参数
        const query = this.props.location.query;
        console.log(query);
        return <h1>详情页</h1>;
    }
}
export default Detail;

注:

  • 通过 query 传参不会将参数暴露在 url 中,但是在刷新当前页面时,参数会丢失。
  • 必须由其他页面跳转过来,参数才会被传递。
  • 使用 query 传参是不需要配置路由表的。

三、使用 state 传值

<Link to={
    {
        pathname: '/about/a1',
        query: {
            id: 1,
            name: 'tom'
        }
    }
}>详情页</Link>

接收参数

import React from 'react'
class Detail extends React.Component {
    render() {
        // 接受 state 的参数
        const state = this.props.location.state;
        console.log(state);
        return <h1>详情页</h1>;
    }
}
export default Detail;

注:

  • query 一样 state 传参时,参数也是加密的。
    react-routerstate 传值提供了各种动态操作的方式。

四、使用 search 传参

<Link to={
    {
        pathname: '/about/a1',
        search: '?id=1&name=tom'
    }
}>详情页</Link>

路由中的 <Switch>

react-router 提供 <Switch> 组件用来根据条件,选择性渲染列表中的一个路由。

给一个需求,用户如果对 url 做一些违规操作,比如输入一个不存在的路由时,展示 404 组件,那么代码可能是这样

<Route path="/about" component={About}/>
<Route path="/user" component={User}/>
{/* 404 组件 */}
<Route component={NoMatch}/>

这种写法,当路由匹配到 '/about''user' 时,<About> 组件和 <User> 会和 404 组件同时渲染。
但实际需求它们是互斥的,这个时候就要用到 <Switch> 组件。

渲染第一个被location匹配到的并且作为子元素的 <Route> 或者 <Redirect>

{/* Switch 和 Link、Route 一样,在使用时需要先从 react-router-dom 中引入 */}
<Switch>
  <Route path="/about" component={About}/>
  <Route path="/user" component={User}/>
  {/* 404 组件 */}
  <Route component={NoMatch}/>
</Switch>

<HashRouter><BrowserRouter>

如果一个页面有这样的基本操作,当前端访问 '/' 时,渲染 <Home> 组件,当访问 '/about' 时,渲染 <About> 组件。

先看路径区别:

BorserRouter:
http://www.xxx.com/about

HashRouter:
http://www.xxx.com/#/about

如果使用 <BrowserRouter>,每次前端做出请求,服务器都要对请求做出分析,并且返回该请求对应的内容给前端,前端渲染即可。

如果使用 <HashRouter>'#' 后面的内容不会传到服务器,无论路由如何,对于服务器端来说,访问的都是 '/',每次请求,服务器都返回同样的内容给浏览器,由浏览器自己解析 '#'之后的内容,渲染对应的内容。

动态路由

react-router 之所以推出 v4 版本,就是因为觉得静态路由还有很多不完善的地方。

react-router v4 允许使用各种条件判断是否需要渲染某个<Route> 组件。

比如某个组件需要用户满足权限才能渲染:

<Switch>
  <Route exact path='/' component={Home}/>
  {
    userState == 4 &&
    <Route exact path='/product' component={Product}/>,
  }  
  <Route path='/about' component={About}/>
</Switch>

猜你喜欢

转载自blog.csdn.net/FlowGuanEr/article/details/100018606