react-router-redux 5:跨导航维护存储状态历史记录
react-router-redux 5: Maintaining store state history across navigation
我目前正在开发一个 React redux 应用程序。当我在浏览器中使用上一个和下一个按钮导航时,url 正在改变并且路线得到正确呈现。但是,redux store 保持最新状态并且不会在导航中进行时间旅行,唯一改变的状态是路由器位置状态。
这是我的 redux 商店:
import {applyMiddleware, combineReducers, createStore} from "redux";
import reducers from "../reducers";
import history from '../history'
import {routerMiddleware, routerReducer} from "react-router-redux";
const middleware = routerMiddleware(history)
const store = createStore(
combineReducers({
...reducers,
router: routerReducer
}),
applyMiddleware(middleware)
)
export default store
应用的索引文件为:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
import 'semantic-ui-css/semantic.min.css';
import {registerObserver} from "react-perf-devtool";
import {Provider} from "react-redux";
import store from "./store";
import {ConnectedRouter} from "react-router-redux";
import history from './history'
if (module.hot) {
module.hot.accept()
}
ReactDOM.render(
<Provider store={store}>
<ConnectedRouter history={history}>
<App />
</ConnectedRouter>
</Provider>,
document.getElementById('root')
);
registerObserver();
registerServiceWorker()
历史如下:
import createHistory from 'history/createBrowserHistory'
const history = createHistory()
export default history
最后,这里是减速器:
import {SET_USER_LOCATION, SET_NEARBY_SHOPS} from "../constants/action-types";
const initialState = {
userLocation: {
latitude: 0.,
longitude: 0.
},
nearbyShops: {
shops: [],
radiusOfSearch: 0.
}
}
const userLocation = (state = initialState.userLocation, action) => {
switch (action.type) {
case SET_USER_LOCATION:
return { latitude: action.payload.latitude, longitude: action.payload.longitude }
default:
return state
}
}
const nearbyShops = (state = initialState.nearbyShops, action) => {
switch (action.type) {
case SET_NEARBY_SHOPS:
return { shops: [...action.payload.shops], radiusOfSearch: action.payload.radiusOfSearch }
default:
return state
}
}
const reducers = { userLocation, nearbyShops }
export default reducers
我使用推送导航到另一条路线:
const mapDispatchToProps = dispatch => bindActionCreators({
setNearbyShops: nearbyShops => setNearbyShops(nearbyShops),
goToNearbyShops: (latitude, longitude, radius) => push(`/nearby/@${latitude},${longitude},${radius}`)
}, dispatch)
我想要的是当我在历史记录中来回导航时同步 userLocation 和 nearbyShops 状态,以便组件以正确的状态而不是最新状态呈现。
这是一张 gif 以进一步解释我要解决的问题:
所以你想让你的 UI 直接依赖于历史状态。
不幸的是,这对于 react-router.
的现有 redux 包装器来说相当繁琐
因此,当历史发生变化时,您的 App
组件将收到道具更新。
您必须以某种方式将这些新道具转发给应对它们作出反应的组件。
你可以例如在您 App
组件的 componentWillReceiveProps
方法中将新信息发送到商店。
或者您可以通过多个组件层将 prop 转发到需要它们的地方,但我不建议这样做。
或者,尝试 https://github.com/mksarge/redux-first-routing
,这样更有意义。
它使路由独立于组件。
另请参阅这篇文章:
https://medium.freecodecamp.org/an-introduction-to-the-redux-first-routing-model-98926ebf53cb
无论如何,userLocation
和 nearbyShops
不应该是缩减器,而是选择器,因为它们的信息可以而且应该从您的历史记录中的地理位置得出。
我目前正在开发一个 React redux 应用程序。当我在浏览器中使用上一个和下一个按钮导航时,url 正在改变并且路线得到正确呈现。但是,redux store 保持最新状态并且不会在导航中进行时间旅行,唯一改变的状态是路由器位置状态。
这是我的 redux 商店:
import {applyMiddleware, combineReducers, createStore} from "redux";
import reducers from "../reducers";
import history from '../history'
import {routerMiddleware, routerReducer} from "react-router-redux";
const middleware = routerMiddleware(history)
const store = createStore(
combineReducers({
...reducers,
router: routerReducer
}),
applyMiddleware(middleware)
)
export default store
应用的索引文件为:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
import 'semantic-ui-css/semantic.min.css';
import {registerObserver} from "react-perf-devtool";
import {Provider} from "react-redux";
import store from "./store";
import {ConnectedRouter} from "react-router-redux";
import history from './history'
if (module.hot) {
module.hot.accept()
}
ReactDOM.render(
<Provider store={store}>
<ConnectedRouter history={history}>
<App />
</ConnectedRouter>
</Provider>,
document.getElementById('root')
);
registerObserver();
registerServiceWorker()
历史如下:
import createHistory from 'history/createBrowserHistory'
const history = createHistory()
export default history
最后,这里是减速器:
import {SET_USER_LOCATION, SET_NEARBY_SHOPS} from "../constants/action-types";
const initialState = {
userLocation: {
latitude: 0.,
longitude: 0.
},
nearbyShops: {
shops: [],
radiusOfSearch: 0.
}
}
const userLocation = (state = initialState.userLocation, action) => {
switch (action.type) {
case SET_USER_LOCATION:
return { latitude: action.payload.latitude, longitude: action.payload.longitude }
default:
return state
}
}
const nearbyShops = (state = initialState.nearbyShops, action) => {
switch (action.type) {
case SET_NEARBY_SHOPS:
return { shops: [...action.payload.shops], radiusOfSearch: action.payload.radiusOfSearch }
default:
return state
}
}
const reducers = { userLocation, nearbyShops }
export default reducers
我使用推送导航到另一条路线:
const mapDispatchToProps = dispatch => bindActionCreators({
setNearbyShops: nearbyShops => setNearbyShops(nearbyShops),
goToNearbyShops: (latitude, longitude, radius) => push(`/nearby/@${latitude},${longitude},${radius}`)
}, dispatch)
我想要的是当我在历史记录中来回导航时同步 userLocation 和 nearbyShops 状态,以便组件以正确的状态而不是最新状态呈现。
这是一张 gif 以进一步解释我要解决的问题:
所以你想让你的 UI 直接依赖于历史状态。 不幸的是,这对于 react-router.
的现有 redux 包装器来说相当繁琐因此,当历史发生变化时,您的 App
组件将收到道具更新。
您必须以某种方式将这些新道具转发给应对它们作出反应的组件。
你可以例如在您 App
组件的 componentWillReceiveProps
方法中将新信息发送到商店。
或者您可以通过多个组件层将 prop 转发到需要它们的地方,但我不建议这样做。
或者,尝试 https://github.com/mksarge/redux-first-routing
,这样更有意义。
它使路由独立于组件。
另请参阅这篇文章:
https://medium.freecodecamp.org/an-introduction-to-the-redux-first-routing-model-98926ebf53cb
无论如何,userLocation
和 nearbyShops
不应该是缩减器,而是选择器,因为它们的信息可以而且应该从您的历史记录中的地理位置得出。