自己写一个ReactRouter

it2022-05-05  140

新建Router.js

import React,{Component} from 'react'; //创建Context const RouterContext=React.createContext() //创建Router class Router extends Component{ constructor(props){ super(props); //state提供更新historypath的方法 this.state={ path:'/', updateHistoryPath:this.updateHistoryPath, router:this }; } updateHistoryPath(path){ window.history.pushState(path,`title-${path}`,path) this.setState((state)=>{ return { path:path } }); } componetDidMount(){ } componentWillUnmount(){ } renderChildren(){ return this.props.children.map((children)=>{ return children }) } render(){ return ( <RouterContext.Provider value={this.state}> {this.renderChildren()} </RouterContext.Provider> ) } }

//创建Link class Link extends Component{

constructor(props){ super(props); } //render函数中消费Context render(){ return ( <RouterContext.Consumer> { ({updateHistoryPath,router})=> ( <a className="link" href="javascript:void(0)" onClick={(e)=>updateHistoryPath.call(router,this.props.to)}> {this.props.children}</a> ) } </RouterContext.Consumer> ) } } //创建Route class Route extends Component{ constructor(props){ super(props); this.state={}; } //render函数中消费Context,根据path进行匹配 render(){ const RenderComponent = this.props.component ; return ( <RouterContext.Consumer> { ({path})=>{ if(path === this.props.path){ return <RenderComponent/> }else{ return <></> } } } </RouterContext.Consumer> ) } } export default Router; export {Link,Route}

使用Router,新建App.js

import React,{Component} from 'react' import Router,{Link,Route} from './router/Router' class Home extends Component{ render() { return <h3>Home</h3> } } class About extends Component{ render() { return <h3>About</h3> } } class List extends Component{ render() { return( <React.Fragment> <h3></h3> <ul> <li> <Link to="/list">列表</Link> </li> </ul> <div> <Route path="/list" component={ListIndex}></Route> <Route path="/list/detail" component={ListDetail}></Route> </div> </React.Fragment> ) } } class ListIndex extends Component{ render(){ let items=[ { name:'张三', id:"zs" }, { name:'李四', id:"ls" } ]; return ( <div> { items.map((item)=><p key={item.id}><Link to={`/list/detail/${item.id}`}>{item.name}</Link></p>) } </div> ) } } class ListDetail extends Component{ render(){ console.log(this); return( <div> <p>www</p> </div> ) } } class App extends Component{ render() { return ( <div> <h1>欢迎回来,菜单如下:</h1> <Router> <ul> <li> <Link to="/">HOME</Link> </li> <li> <Link to="/about">ABOUT</Link> </li> <li> <Link to="/list">LIST</Link> </li> </ul> <h3>主体内容:</h3> <div> <Route path="/" component={Home}></Route> <Route path="/about" component={About}></Route> <Route path="/list" component={List}></Route> </div> </Router> </div> </div> ) } } export default App;

为什么要用Context

Router作为父组件,维护了path,并提供更新path的方法updateHistoryPath 子组件Link需要调用updateHistoryPath,Link作为子组件是通过父组件调用this.props.children 因此无法传递updateHistoryPath,这种情况使用Context作为状态传递

最新回复(0)