作用
加强了React Router库中history这个实例,以允许将history中接受到的变化反应到state中去
用法
import React from "react";import ReactDOM from "react-dom";import { createStore, combineReducers } from "redux";import { Provider } from "react-redux";import { Router, Route, browserHistory } from "react-router";import { syncHistoryWithStore, routerReducer,push,routerMiddleware,applyMiddleware } from "react-router-redux";import reducers from "<project-path>/reducers";const history = syncHistoryWithStore(browserHistory, store)const middleware = routerMiddleware(browserHistory)const store = createStore(combineReducers({...reducers,routing: routerReducer,}),applyMiddleware(middleware));// 注册listen监听函数history.listen(location => analyticsService.track(location.pathname))ReactDOM.render(<Provider store={store}>{ /* Tell the Router to use our enhanced history */ }<Router history={history}><Route path="/" component={App}><Route path="foo" component={Foo}/><Route path="bar" component={Bar}/></Route></Router></Provider>,document.getElementById('mount'))// 路由跳转store.dispatch(push('/foo'))
syncHistoryWithStore源码
- 包装原生history
- 注册listen监听函数(触发dispatch更新store.location)
- 修改listen监听函数(通过store.subscribe实现) ```typescript
// 当locaiton改变的时候dispatch const handleLocationChange = (location) => { store.dispatch({ type: LOCATION_CHANGE, payload: location, }); };
// 返回取消订阅的函数 unsubscribeFromHistory = history.listen(handleLocationChange);
// 返回强化后的history,增强listen方法,通过store.subscribe监听location变化 return { …history, // 重写listen方法 listen(listener) { let lastPublishedLocation = getLocationInStore(true);
// 对比location,通过store订阅控制listener执行
let unsubscribed = false;
const unsubscribeFromStore = store.subscribe(() => {
const currentLocation = getLocationInStore(true);
if (currentLocation === lastPublishedLocation) {
return;
}
lastPublishedLocation = currentLocation;
if (!unsubscribed) {
listener(lastPublishedLocation);
}
});
return () => {
unsubscribed = true;
unsubscribeFromStore();
};
}, // 取消listen订阅 unsubscribe() { if (adjustUrlOnReplay) { unsubscribeFromStore(); } unsubscribeFromHistory(); }, };
push源码
```typescript
function updateLocation(method) {
return (...args) => ({
type: CALL_HISTORY_METHOD,
payload: { method, args }
})
}
/**
* 重写原生history api
* 通过routerMiddleware捕获参数,调用原生的history api
*/
export const push = updateLocation('push')
// ***********************
export default function routerMiddleware(history) {
return () => next => action => {
if (action.type !== CALL_HISTORY_METHOD) {
return next(action)
}
const { payload: { method, args } } = action
history[method](...args)
}
}
