react-router2 - 實現 HashRouter 和 Route組件理解實現原理

參考源碼庫的Router.js

原生庫的使用

官方路由使用效果演示
在這裏插入圖片描述

實現思路

在這裏插入圖片描述

1. 先導出倆組件

react-router-dom / index.js

import Route from './Route';
import HashRouter from './HashRouter';
export { HashRouter, Route };

2. 創建上下文對象

import React from 'react';
export default React.createContext();

3. HashRouter組件

import React, { Component } from 'react';
import Context from './Context';
// #/ =>  /, #/home => /home , #/about => /about
let hash = () =>  window.location.hash.slice(1);
class HashRouter extends Component {
  state = {
    location: {
      pathname: hash()|| "/",  // 第一次初始化的時候可能沒有值,先給個默認的
    },
  };
  UNSAFE_componentWillMount() {
    // 如果hash 值改變了,就改變狀態
    window.addEventListener('hashchange', () => {
      this.setState({
        location: {
          pathname: hash() || '/',  // 如果有就使用你的,否則使用默認的 /
        },
      });
    });
  }
  render = () => (
    <Context.Provider value={this.state}>
      {this.props.children}
    </Context.Provider>
  );
}
export default HashRouter;

4. Route 組件

import React, { PureComponent } from 'react';
import Context from './Context';
class Route extends PureComponent {
  static contextType = Context;
  render() {
    // 獲取到用戶傳入的path 和 組件
    const { component: RouteComponent, path } = this.props;
    // 獲取到監聽到的變化後的hash值
    const { pathname } = this.context.location;
    // 比較, 如果相等,就渲染對應的組件,否則,渲染null
    return pathname === path ? <RouteComponent /> : null;
  }
}
export default Route;

因爲,現在沒有做跳轉的邏輯, 需要你手動在地址欄改變hash值, 然後按下enter 確定, 組件纔會變化,手寫效果演示

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章