我受到 Alexander Bykov 的回答 + redux-persist 的启发,并制作了这个 - 一个增强器,可以实现哈希的双向绑定store。
import { applyMiddleware } from 'redux';
import createActionBuffer from 'redux-action-buffer';
const CHANGE_HASH = '@@hashSynch/CHANGE_HASH';
const hashEnhancer = (hashFromState, stateFromStateAndHash) => createStore => (reducer, initialState) => {
const store = createStore(liftReducer(reducer), initialState, applyMiddleware(createActionBuffer(CHANGE_HASH)));
store.subscribe(() => {
const hash = hashFromState(store.getState());
if (window.location.hash !== hash) {
window.location.hash = hash;
}
});
window.addEventListener('hashchange', () => {
const hash = window.location.hash;
const savedHash = hashFromState(store.getState());
if (savedHash !== hash) {
store.dispatch({
type: CHANGE_HASH,
hash
});
}
}, false);
store.dispatch({
type: CHANGE_HASH,
hash: window.location.hash
});
function liftReducer(reducer) {
return (state, action) => {
if (action.type !== CHANGE_HASH) {
return reducer(state, action);
} else {
return stateFromStateAndHash(state, action.hash);
}
}
}
return {
...store,
replaceReducer: (reducer) => {
return store.replaceReducer(liftReducer(reducer))
}
}
};
这样使用:
export const store = createStore(
reducer,
initialState,
hashEnhancer(hashFromState, stateFromStateAndHash)
);
其中 hashFromState 是 hash=>state 类型的函数,stateFromStateAndHash 是 function (state, hash) => state。
它可能是过度设计的,而路由器会更简单,我根本不了解 react-router 或 react-router-redux。