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 communication
context
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 by
hashRouter
A 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 the
url
Address, 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 the
link
Tag 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>
<Link to='/setting'>setting</Link>
<Link to='/user'>user</Link>
</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