React router v4笔记

使用npm来进行安装

npm install --save react-router react-router-dom

ReactRouter动态传值

  1. 设置, 以:开始的,然后紧跟着你传递的key(键名称)名称。

    <Route path="/list/:id" component={List} />
  2. Link上传递值

    <li><Link to="/list/123">列表</Link> </li>

    to属性的值可以是一个字符串,也可以是一个location(pathname, hash, state和search)对象。

  3. 组件上接收并显示传递值

    componentDidMount(){
        console.log(this.props.match)
    }

    然后在浏览器的控制台中可以看到打印出的对象,对象包括三个部分:

    • patch:自己定义的路由规则,可以清楚的看到是可以产地id参数的。

    • url: 真实的访问路径,这上面可以清楚的看到传递过来的参数是什么。

    • params:传递过来的参数,key和value值。

理解和使用Route

Route组件可以使用如下的属性:

  • path属性,字符串类型,它的值就是用来匹配url的。

  • component属性,它的值是一个组件。在path匹配成功之后会绘制这个组件。

  • exact属性,这个属性用来指明这个路由是不是排他的匹配。

  • strict属性, 这个属性指明路径只匹配以斜线结尾的路径。

    还有其他的一些属性,可以用来代替component属性。

  • render属性,一个返回React组件的方法。传说中的rencer-prop就是从这里来的。

  • children属性,返回一个React组件的方法。只不过这个总是会绘制,即使没有匹配的路径的时候

    数的时候是用component属性就可以满足。但是,某些情况下你不得不使用render或children属性。

ReactRouter重定向-Redirect使用

  1. 标签式重定向

    这个一般用在不是很复杂的业务逻辑中,比如我们进入Index组件,然后Index组件,直接重定向到Home组件。

    //引入Redirect
    import { Link , Redirect } from "react-router-dom";
    
    //引入Redirect后,直接在render函数里使用就可以了
    <Redirect to="/home/" />
  2. 编程式重定向

    //直接在构造函数constructor中加入下面的重定向代码
    this.props.history.push("/home/");

进阶

React router的Route中component和render属性的使用
  1. component ---只有当位置匹配时才会渲染的 React 组件

    当您使用 component(而不是 render 或 children )Route 使用从给定组件 React.createElement 创建新的 React element。这意味着,如果您为 component 道具提供了内联功能,则每次渲染都会创建一个新组件。这会导致现有组件卸载和安装新组件,而不是仅更新现有组件。当使用内联函数进行内联渲染时,使用 render 或者 children(如下所示)

  2. render: func ---这允许方便的内联渲染和包裹,而不是上面那种不想要的重新安装的解释

    您可以传递一个在位置匹配时调用的函数,而不是使用属性为您创建新的 React element component,该 render 属性接收所有相同的 route props 的 component 渲染属性。

    警告: Route component 优先于 Route render 因此不要在同一个 Route 使用两者。

通过一个小例子来说明:

import React from 'react';
import ReactDOM from 'react-dom';
import {BrowserRouter, Route} from "react-router-dom";

class Bar extends React.Component {

    componentDidMount() {
        console.log("componentDidMount")
    }

    render() {
        return (
            <div>Bar</div>
        )
    }
}

class App extends React.Component {

    constructor(prop) {
        super(prop);
        this.state = {idx: 1}
    }

    handleClick = () => {
        this.setState(state => ({idx: state.idx + 1}))
    };

    render() {
        return (
            <div>
                <div>
                    {this.state.idx}
                    <button onClick={this.handleClick}>add</button>
                </div>
                <div>
                    <BrowserRouter>
                        <Route component={Bar}/>
                    </BrowserRouter>
                </div>
            </div>
        );
    }
}


ReactDOM.render(<App/>, document.getElementById('root'));

//上面的代码中,App组件内有一个简单的Bar组件,通过component属性被Route引用。
//<Route component={Bar}/>
//此时在页面中点击按钮,Bar组件的componentDidMount并不会被触发。

假设现在需要在Bar组件中接受App中的idx,需要将idx作为props传递给Bar,此时可以写成如下代码

import React from 'react';
import ReactDOM from 'react-dom';
import {BrowserRouter, Route} from "react-router-dom";

class Bar extends React.Component {

    componentDidMount() {
        console.log("componentDidMount")
    }

    render() {
        const {idx} = this.props;
        return (
            <div>in Bar : {idx}</div>
        )
    }
}

class App extends React.Component {

    constructor(prop) {
        super(prop);
        this.state = {idx: 1}
    }

    handleClick = () => {
        this.setState(state => ({idx: state.idx + 1}))
    };

    render() {
        return (
            <div>
                <div>
                    {this.state.idx}
                    <button onClick={this.handleClick}>add</button>
                </div>
                <div>
                    <BrowserRouter>
                        <Route component={() => (<Bar idx={this.state.idx}/>)}/>
                    </BrowserRouter>
                </div>
            </div>
        );
    }
}


ReactDOM.render(<App/>, document.getElementById('root'));

然而此时点击按钮,发现Bar的componentDidMount一直被调用,所以正确的写法应该是:

<Route render={() => (<Bar idx={this.state.idx}/>)}/>
//此时Bar组件就不会出现重复的unmounting和mounting了。

其背后的原理在于,react在比较组件状态以便决定如何更新dom节点时,首先要比较组件的type和key。在使用<Route component={() => (<Bar idx={this.state.idx}/>)}/>时,由于调用了React.createElement,组件的type不是Bar这个类,而是一个匿名函数。App组件每次render时都生成一个新的匿名函数,导致生成的组件的type总是不相同,所以会产生重复的unmounting和mounting。

react路由懒加载(异步组件)------react-loadable

npm地址

  1. 安装

    cnpm install react-loadable
  2. 封装loadable

    首先,我们建一个util src/util/loadable.js

    import React from 'react';
    import Loadable from 'react-loadable';
    
    //通用的过场组件
    const loadingComponent =()=>{
        return (
            <div>loading</div>
        ) 
    }
    
    //过场组件默认采用通用的,若传入了loading,则采用传入的过场组件
    export default (loader,loading = loadingComponent)=>{
        return Loadable({
            loader,
            loading
        });
    }
  3. 调用

    import loadable from '../util/loadable'
    
    const Home = loadable(()=>import('@pages/home'))

    react-loadable是以组件级别来分割代码的,这意味着,我们不仅可以根据路由按需加载,还可以根据组件按需加载。

参考

React Router 印记中文

React Router 使用教程

利用react-router4的react-router-config做路由鉴权

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值