Implement a React-Router

Try wrapping a React-Router yourself

The main component communication encapsulates the HashRouter with React. CreateContext

context.js

  • This is for cross-level communicationcontext
import React from 'react';

const {Provider, Consumer} = React.createContext()

export {Provider, Consumer}
Copy the code

HashRouter.js

  • Outermost root component
  • Used to listen for route changes, and provide modified route methods, provided byhashRouterA child component of a package
import React, { Component } from 'react'; import { Provider } from './context' export default class HashRouter extends Component { constructor() { super() this.state = { location: { pathname: window.location.hash.slice(1) || '/' }, history: {}} componentDidMount() {// Default hash without, Jump to/the window. The location. The hash = window. The location. The hash | | '/' / / monitor reset the status window. The hash value change addEventListener (' hashchange ', () => { this.setState({ location: { ... this.state.location, pathname: window.location.hash.slice(1) || '/' } }) }) } render() { let value = { location: this.state.location, history: { push(to) { window.location.hash = to } } } return (<Provider value={value}>
        {this.props.children}
      </Provider>); }}Copy the code

Route.js

  • By matching theurlAddress, render the corresponding component
import React, { Component } from 'react'
import { Consumer } from './context'
const { pathToRegexp } = require("path-to-regexp");

export default class Route extends Component {
  render() {
    console.log('props'.this.props);
    
    return (
      <Consumer>{ (state) => { console.log(state) let {path, component:Component, Exact =false} = this.props let pathName = state.location.pathname // To implement a regular match for the path. reg = pathToRegexp(path, [], {end: exact}) let result = pathname.match(reg) if (result) { return<Component></Component>
            }
            
            return null
          }
        }
      </Consumer>)}}Copy the code

Link.js

  • Click on thelinkTag to change the routing address
import React, { Component } from 'react'
import { Consumer } from './context'
export default class Link extends Component {
  render() {
    return (
      <Consumer>
        {
          (state) => {
            return <a onClick={()= > {
              state.history.push(this.props.to)
            }}>{this.props.children}</a>}}</Consumer>)}}Copy the code

Redirect.js

  • Redirects pages to the home page when all pages do not match
import React, { Component } from 'react';
import { Consumer } from './context'


export default class Redirect extends Component {
  render() {
    return <Consumer>Push (this.props. To) return null}}</Consumer>}}Copy the code

switch.js

  • Only the first matching route is matched
import React, { Component } from 'react'
import { Consumer } from './context'
const { pathToRegexp } = require("path-to-regexp");

export default class Switch extends Component {
  render() {
    return (
      <Consumer>
        {
          (state) => {
            let pathname = state.location.pathname
            let children = this.props.children
            for (let i = 0; i < children.length; i{+ +)let child = children[i]
              let path = child.props.path || ''
              let reg = pathToRegexp(path, [], {end: false})
              let result = pathname.match(reg)
              if (result{/ /switchThe match is successfulreturn child}}return null
          }
        }
      </Consumer>)}}Copy the code
      <HashRouter>
        <div>
          <div>
            <Link to='/home'>home</Link> &nbsp;
            <Link to='/setting'>setting</Link>&nbsp;
            <Link to='/user'>user</Link>&nbsp;
          </div>
          <div>
            <Switch>
              <Route path='/index' component={Index} />
              <Route path='/home' component={Home} />
              <Route path='/setting' component={Setting} />
              <Route path='/user' component={User} />
              <Redirect to="/"></Redirect>
            </Switch>
          </div>
        </div>
      </HashRouter>
Copy the code