react-router@4.2.0系列-Redirect组件

Redirect组件
开发中遇到的需求,ajax请求返回状态如果成功则跳转成功页面(很常见吧)。由于是单页应用,跳转前后用Route组件渲染,跳转用Redirect进行控制。测试demo结构如下:

测试结构

 

测试结构

其中index.html,server.js和wepack.config.dev.js是我在写webpack热更新所用来编译项目的文件,大家可以用自己方式。

index.js

import React,{Component} from 'react'
import {render} from 'react-dom'
import { BrowserRouter as Router, Route ,Redirect,Switch} from "react-router-dom";


const AppMain = document.getElementById("main");


class Page_01 extends Component{
    constructor(props){
        super(props);
        this.state={
            redirect:false
        }
        this.redirectHanlder = this.redirectHanlder.bind(this);
    }

    redirectHanlder(){
        this.setState({
            redirect:true
        });
    }

    render(){
        let {redirect} = this.state;
        return (
            redirect
            ?
            <Redirect 
                to={
                    {
                        pathname:"/p2",    (1)
                        search:"p1=1&p2=2",  (2)
                        state:{"name":"kiramario","age":26} (3)
                    }
                } 
            />
            :
            <div>
                <h2>Page_01</h2>
                <button onClick={this.redirectHanlder}>jump to page 2</button>
            </div>

        );
    }
}


class Page_02 extends Component{
    constructor(props){
        super(props);
        console.log(this.props)
    }

    render(){
        return (
            <div>
                <h2>Page_02</h2>
            </div>
        );
    }
}


render(
    <Router>
        <Switch> (4)
            <Route exact path="/" component={Page_01}/>

            <Route path="/p2" component={Page_02}/>

            <Redirect exact strict from="/dd/" to="/p2" /> (5)

        </Switch>
    </Router>,
    AppMain
);

1、 渲染页面时,Router根据Route中path的值,按顺序去匹配当前浏览器的location.pathname并加载。此例中在浏览器地址中输入http://127.0.0.1:9090 渲染Page_01,输入http://127.0.0.1:9090/p2渲染Page_02。 
2、Switch组件,如上代码中(4)部分,表示Router按顺序去匹配当前url。 匹配到第一个就不在往下继续寻找。

Redirect本质上是一个组件,因此需要放在rende函数中,index中的逻辑如下:

在浏览器中输入http://127.0.0.1:9090,此时会渲染出Page_01
在Page_01模块中点击jump to page 2按钮,调用setState方法,将this.state.redirect设置为true,组件重新渲染,返回Redirect组件。
浏览器地址栏跳转到http://127.0.0.1:9090/p2,渲染Page_02模块。在Page_02的构造函数中console.log(this.props),结构如下图: 

router实现路由切换的原理是用到了H5 API中的history,我们看到this.props.history有push和replace方法实际上是原生接口history.replaceState和history.pushState的封装(写这段话的时候比较虚,主要是因为我是通过测试代码来验证,并没有去找源代码)
 

 

router实现路由切换的原理是用到了H5 API中的history,我们看到this.props.history有push和replace方法实际上是原生接口history.replaceState和history.pushState的封装(写这段话的时候比较虚,主要是因为我是通过测试代码来验证,并没有去找源代码)

to
参数表示渲染Redirect组件后跳转的url地址,有两种表达方式,string或者 json对象,string形式后面跟要跳转的url字符串。json对象里面有3个参数。

pathname,跳转到的URL。
search,跳转后的url参数。此例中,跳转后的url是http://127.0.0.1:9090/p2?p1=1&p2=2
state,会保存在this.history.location.state中,可以借此保存数据
push
通过this.props的截图可以看到,this.props.history中的action为REPLACE,表示在默认情况下,它调用的是history.replaceState方法,当前浏览历史被修改,因此浏览器返回键无效。

加上push参数会调用history.pushState, <Redirect push to={{...} /> 此时浏览器将url加入到浏览历史中,浏览器后退键有效,在此例中后退会回到http://127.0.0.1:9090,Page_01模块。

打开Redirect.js源码,找到这一段。可以看到,如果有push,调用hisotry.push (history.pushState的封装)
 

Redirect.prototype.perform = function perform() {
    var history = this.context.router.history;
    var _props = this.props,
        push = _props.push,
        to = _props.to;


    if (push) {
      history.push(to);
    } else {
      history.replace(to);
    }
};

from,exact,strict
这三个参数只能用在Switch组件下面的Redirect组件中,如上代码所示。 
<Redirect exact strict from="/dd/" to="/p2" />

from:表示浏览器地址中的匹配跳转的pathname,如果当前from匹配到当前浏览器pathname,触发此Redirect。浏览器输入http://127.0.0.1:9090/dd/时会立马跳转到http://127.0.0.1:9090/p2

exact :规定from匹配pathname时是精确还是模糊。

精确:from=”/dd” 必须匹配 http://127.0.0.1:9090/dd
模糊:from=”/dd“ 可以匹配http://127.0.0.1:9090/dd/ff/ee
strict:表示是否匹配pathname部分末尾的“/”符号,如果有此参数,Redirect组件的from和浏览器pathname匹配时要考虑末尾的”/”。例如(5)所示,from=”/dd/” 必须匹配 http://127.0.0.1:9090/dd/而非 http://127.0.0.1:9090/dd
 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值