美文网首页
react-router-dom实现原理

react-router-dom实现原理

作者: 祝家庄打烊 | 来源:发表于2020-02-12 13:58 被阅读0次

    语法分析(react-router-dom)

    一、安装react-router-dom
    npm install react-router-dom --save-dev
    二、在根组件上配置路由,引用react-router-dom结构{ HashRouter as Router, Route ,Link ,Redirect ,Switch },HashRouter组件是路由的根组件,定义属性和方法传递给子组件。Router组件进行路由,指定每个路由跳转到相应的组件。Link组件指定跳转链接。Redirect组件路由重定向,不管什么情况下,都会跳转当前指定的路径,和switch组件联合起来一起调用,当路径匹配到路由,不在往下匹配。

    import React from 'react';
    import './App.css';
    import { HashRouter as Router, Route ,Link ,Redirect ,Switch } from './react-router-dom'
    import Home from "./view/Home";
    import Profile from "./view/Profile";
    import Detail from "./view/Detail";
    
    function App() {
      return (
        <div className="App">
          <Router>
            <div>
              <div>
                <Link to="/">首页</Link>
                <Link to="/profile">主页</Link>
                <Link to="/detail">详情页</Link>
              </div>
              <div>
                <Switch>
                  <Route path="/home" exact component={Home}></Route>
                  <Route path="/profile" exact component={Profile}></Route>
                  <Route path="/detail" exact component={Detail}></Route>
                  <Redirect to="/home"></Redirect>
                </Switch>
              </div>
            </div>
          </Router>
        </div>
      );
    }
    export default App;
    

    实现react-router-dom

    一、首先了解HashRouter和HistoryRouter的区别,HashRouter是根据路径"#"后面参数进行匹配路由,在服务器上匹配的路径,始终只有一个。HistoryRouter是根据"/"后面的参数匹配路由,在服务器上会匹配多个路由地址,在服务器上并不会存在这些地址,报错404。
    二、HashRouter定义状态,状态存储默认pathname哈希值和push方法路由跳转。

    componentDidMount(){
        let _that = this;
        window.location.hash = window.location.hash || "/";
        window.addEventListener("hashchange",function(){
            _that.setState({
                ..._that.state,
                location:{
                    ..._that.state.location,
                    pathname: window.location.hash.slice(1) || "/"
                }
            })
        })
    }
    

    三、HashRouter根组件上状态传递给子组件,用到react16的新属性React.createContext()

    import React from 'react';
    let {Provider ,Consumer} = React.createContext();
    export {Provider ,Consumer};
    

    四、Route组件进行路由匹配,匹配到哪个组件,进行渲染,pathToRegexp模块可以匹配链接地址的多个层级。

    render(){
        let {path ,component:Component} = this.props;
        return <Consumer>
            {(state)=>{
                let exact = this.props.exact || false;
                let reg = pathToRegexp(path,[],{end:exact});
                let {pathname} = state.location;
                if(reg.test(pathname)){
                    return <Component {...state}></Component>;
                }
                return null;
            }}
        </Consumer>
    }
    

    五、Link和Redirect组件指定元素的click事件,调用根组件push方法跳转。

    render(){
       return <Consumer>
            {(state)=>{
                return <a onClick={()=>state.history.push(this.props.to)}>
                    {this.props.children}
                </a>
            }}
       </Consumer>
    }
    

    六、Switch组件遍历子组件的pathname是否等于地址栏的哈希值,只有相等,才返回当前组件,Redirect组件除外。

    render(){
       return <Consumer>
            {(state)=>{
                let exact = false;
                let pathname = state.location.pathname;
                let children = this.props.children
                for(var i=0;i<children.length;i++){
                    let child = children[i];
                    let path = child.props.path || '';
                    let reg = pathToRegexp(path,[],{end:exact});
                    if(reg.test(pathname)){
                        return child;
                    }
                };
                return null;
            }}
        </Consumer>
    }
    

    项目案例

    相关文章

      网友评论

          本文标题:react-router-dom实现原理

          本文链接:https://www.haomeiwen.com/subject/plnqfhtx.html