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> ) } }