React Router Redux返回导致无限循环



我有一个用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
}

这里有什么问题吗?

此问题很可能是由以下原因引起的:

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

通过这种方式,您可以保证在正确的时间正确更新商店。

最新更新