在带有 SSR 的 React Redux 架构中使用 history.js 存储 browserHistory
Store browserHistory using history.js in react redux architecture with SSR
如何保留访问 SSR react-redux 应用程序的用户的完整路由器历史记录?我试过修改 react-redux-router 包的 reducer.js 文件......但是当用户通过 SSR 加载时,历史数组被重置。
/**
* This action type will be dispatched when your history
* receives a location change.
*/
export const LOCATION_CHANGE = '@@router/LOCATION_CHANGE'
const initialState = {
locationBeforeTransitions: null,
locationHistory: []
}
/**
* This reducer will update the state with the most recent location history
* has transitioned to. This may not be in sync with the router, particularly
* if you have asynchronously-loaded routes, so reading from and relying on
* this state is discouraged.
*/
export function routerReducer(state = initialState, { type, payload } = {}) {
if (type === LOCATION_CHANGE) {
return { ...state,
locationBeforeTransitions: payload,
locationHistory: state.locationHistory.concat([payload]) }
}
return state
}
参考:https://github.com/reactjs/react-router-redux/blob/master/src/reducer.js
不过,我认为这是应该在中间件中实现的。
无论如何,这(存储整个之前的会话历史记录)似乎是一个足够常见的用例,也许有人已经制定了最佳实践。??
也许甚至这个完整的历史也可以通过 react-router w/o react-router-redux 中的 historyjs 对象访问。
我正在寻找有关如何在 redux 状态下存储用户会话的完整历史记录并在用户关闭浏览器或导航时 post 将其存储到我的 api 服务器的答案远离现场。 (如果这不可能,我可以在每次导航时 post 它。)然后我想在用户主页上的 'recently viewed' 页面列表中显示此历史记录。
首先,您不必干预 react-redux-router
的内部结构。
如您在提供的代码中所见,react-redux-router
导出一个 LOCATION_CHANGE
操作。
您可以在自己的减速器中使用此操作。这是一个例子:
// locationHistoryReducer.js
import { LOCATION_CHANGE } from 'react-router-redux';
export default function locationHistory(state = [], action) {
if (action.type === LOCATION_CHANGE) {
return state.concat([action.payload]);
}
return state;
}
然而,这可能是不必要的。您认为这可以通过 middleware 实现的假设是正确的。这是中间件层的示例:
const historySaver = store => next => action => {
if (action.type === LOCATION_CHANGE) {
// Do whatever you wish with action.payload
// Send it an HTTP request to the server, save it in a cookie, localStorage, etc.
}
return next(action)
}
以下是在商店中应用该层的方法:
let store = createStore(
combineReducers(reducers),
applyMiddleware(
historySaver
)
)
现在,您如何保存和加载数据完全取决于您(与 react-router 和浏览器的历史记录无关)。
在官方文档中,他们建议 injecting the initial state on the server side 使用 window.__PRELOADED_STATE__
变量。
如何保留访问 SSR react-redux 应用程序的用户的完整路由器历史记录?我试过修改 react-redux-router 包的 reducer.js 文件......但是当用户通过 SSR 加载时,历史数组被重置。
/**
* This action type will be dispatched when your history
* receives a location change.
*/
export const LOCATION_CHANGE = '@@router/LOCATION_CHANGE'
const initialState = {
locationBeforeTransitions: null,
locationHistory: []
}
/**
* This reducer will update the state with the most recent location history
* has transitioned to. This may not be in sync with the router, particularly
* if you have asynchronously-loaded routes, so reading from and relying on
* this state is discouraged.
*/
export function routerReducer(state = initialState, { type, payload } = {}) {
if (type === LOCATION_CHANGE) {
return { ...state,
locationBeforeTransitions: payload,
locationHistory: state.locationHistory.concat([payload]) }
}
return state
}
参考:https://github.com/reactjs/react-router-redux/blob/master/src/reducer.js
不过,我认为这是应该在中间件中实现的。
无论如何,这(存储整个之前的会话历史记录)似乎是一个足够常见的用例,也许有人已经制定了最佳实践。??
也许甚至这个完整的历史也可以通过 react-router w/o react-router-redux 中的 historyjs 对象访问。
我正在寻找有关如何在 redux 状态下存储用户会话的完整历史记录并在用户关闭浏览器或导航时 post 将其存储到我的 api 服务器的答案远离现场。 (如果这不可能,我可以在每次导航时 post 它。)然后我想在用户主页上的 'recently viewed' 页面列表中显示此历史记录。
首先,您不必干预 react-redux-router
的内部结构。
如您在提供的代码中所见,react-redux-router
导出一个 LOCATION_CHANGE
操作。
您可以在自己的减速器中使用此操作。这是一个例子:
// locationHistoryReducer.js
import { LOCATION_CHANGE } from 'react-router-redux';
export default function locationHistory(state = [], action) {
if (action.type === LOCATION_CHANGE) {
return state.concat([action.payload]);
}
return state;
}
然而,这可能是不必要的。您认为这可以通过 middleware 实现的假设是正确的。这是中间件层的示例:
const historySaver = store => next => action => {
if (action.type === LOCATION_CHANGE) {
// Do whatever you wish with action.payload
// Send it an HTTP request to the server, save it in a cookie, localStorage, etc.
}
return next(action)
}
以下是在商店中应用该层的方法:
let store = createStore(
combineReducers(reducers),
applyMiddleware(
historySaver
)
)
现在,您如何保存和加载数据完全取决于您(与 react-router 和浏览器的历史记录无关)。
在官方文档中,他们建议 injecting the initial state on the server side 使用 window.__PRELOADED_STATE__
变量。