我有一个使用React + Redux构建的应用程序。我使用React Router和React Router Redux进行路由。我注意到很奇怪的行为。单击后退按钮一次,从0到-1就可以了。但是当你第二次点击它,打算从-1到-2时,你会回到0.后续点击循环在0和-1之间。这种行为与推送到最后一个位置的历史记录一致,而不是一致。这是这些库的预期行为吗?如果不是我错误地使用它们?
以下是我认为相关的代码段。文件不完整(太大)但我认为这是必不可少的,愿意在需要时分享更多。
root.tsx
:
import { Router, browserHistory } from 'react-router'
import { syncHistoryWithStore } from 'react-router-redux'
const history = syncHistoryWithStore(browserHistory, store)
const renderAsyncConnect = props =>
<ReduxAsyncConnect
{...props}
helpers={{ client }}
filter={notDeferredItems}
/>
const Root = () =>
<Provider store={store} key="provider">
<Router render={renderAsyncConnect} history={history}>
{routes}
</Router>
</Provider>
export default Root
我还有一个中间件监听推送操作。我知道我被建议使用history.listen
,但是这个中间件在竞争条件方面非常强大,并且只是在我们转换系统时暂时兼容。
以下是路由中间件之后的中间件的净效果:
const browseStateMiddleware = ({ dispatch, getState }) => next => action => {
if (action.type === '@@router/LOCATION_CHANGE') {
// some dispatching of actions deleted here for clarity
return next(action)
}
}
create-store.js
:
import thunk from 'redux-thunk'
import { composeWithDevTools } from 'redux-devtools-extension/logOnly'
import { createStore as _createStore, applyMiddleware } from 'redux'
import { routerMiddleware } from 'react-router-redux'
import clientMiddleware from './middleware/client-middleware'
import browseStateMiddleware from './middleware/browse-state-middleware'
import combinedReducers from './modules/reducer'
import types from './modules/account/types'
export default function createStore(history, client, data, persister) {
const storeData = data
// Sync dispatched route actions to the history
const reduxRouterMiddleware = routerMiddleware(history)
const middleware = [
browseStateMiddleware,
reduxRouterMiddleware,
clientMiddleware(client),
analyticsMiddleware,
thunk,
]
const composeEnhancers = composeWithDevTools(
{
// options like actionSanitizer, stateSanitizer
}
)
// See https://stackoverflow.com/questions/35622588/how-to-reset-the-state-of-a-redux-store/35641992#35641992
const rootReducer = (state, action) => {
if (action.type === types.LOGOUT) {
if (persister) {
persister.clear()
}
return combinedReducers(undefined, action)
}
return combinedReducers(state, action)
}
const store = _createStore(
rootReducer,
storeData,
composeEnhancers(
applyMiddleware(...middleware)
// other store enhancers
)
)
window.store = store
if (__DEVELOPMENT__ && module.hot) {
module.hot.accept('./modules/reducer', () => {
store.replaceReducer(System.import('./modules/reducer'))
})
}
return store
}
这里有什么问题吗?
答案 0 :(得分:2)
此问题很可能是由以下原因引起的:
const browseStateMiddleware = ({ dispatch, getState }) => next => action => {
if (action.type === '@@router/LOCATION_CHANGE') {
// some dispatching of actions deleted here for clarity
return next(action)
}
}
您分发的动作是在商店中更新路由之前发生的,这导致此行为源自react-router-redux(我已经看到它是在4.0.8版本中复制的)。
一种解决方法是执行以下操作:
const browseStateMiddleware = ({ dispatch, getState }) => next => action => {
if (action.type === '@@router/LOCATION_CHANGE') {
next(action);
// dispatch your actions here
return;
}
}
这样可以保证您在正确的时间正确更新商店。