connected-react-router
这个库帮咱们实现了在 redux
中操做路由方法,并将路由变化的信息同步在 redux
的 store
中。react
actions
封装 push
、replace
、go
等主要方法middleware
拦截 actions
信息,触发封装好的 action
方法reducer
新增 router
的state信息ConnectedRouter
组件监听路由变化,更新路由信息到 store
store
import push from "./push"; import connectRouter from './connectRouter' import ConnectedRouter from './ConnectedRouter'; import routerMiddleware from './routerMiddleware' export { push, connectRouter, ConnectedRouter, routerMiddleware, }
向外暴露用到的type
常量git
export const LOCATION_CHANGE = "@@router/LOCATION_CHANGE"; // 路由变化 export const CALL_HISTORY_METHOD = "@@router/CALL_HISTORY_METHOD"; // 触发路由方法
封装咱们的push
方法,这里是返回一个action
信息,接下来的中间件能够截取到这个action
,并触发对应的method
操做github
import * as TYPES from "./constant"; export default function(path){ return { type: TYPES.LOCATION_CHANGE, payload:{ method:"push", path } } }
routerMiddleware
是一个中间件,如上面所述,截取action
,若是是本身定义的type
,拦截并触发对应的路由方法,不然执行下一个中间件redux
import * as TYPES from "./constant"; export default (history)=>(store)=>(next)=>(action)=>{ if (action.type === TYPES.LOCATION_CHANGE) { const { method, path } = action.payload; history[method](path); } else { next(action); } }
connectRouter
就是咱们记录信息的reducer
了,可是路由state
信息须要同步,就须要监听路由的变化,并dispatch
到store
中。react-router
import * as TYPES from "./constant" let initState = {} export default function(history) { return (state = initState,action)=>{ switch (action.type) { case TYPES.CALL_HISTORY_METHOD: return action.payload; default: return state; } } }
ConnectedRouter
的目的就是为了监听路由的变化,并触发store
的更新,这样路由就能作到同步更新了。this
import * as TYPES from "./constant" import React, { Component } from 'react' import { Router } from "react-router"; import { ReactReduxContext }from "react-redux"; export default class ConnectedRouter extends Component { static contextType = ReactReduxContext; componentDidMount(){ this.unlisten = this.props.history.listen((payload)=>{ this.context.store.dispatch({ type: TYPES.CALL_HISTORY_METHOD, payload }) }) } componentWillUnmount(){ this.unlisten(); } render() { const {history,children} = this.props; return ( <Router history={history}> {children} </Router> ) } }