使用history.js在browser redux架构中使用SSR

时间:2016-06-24 11:51:04

标签: redux react-router browser-history history.js react-router-redux

如何能够持久访问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状态下存储用户会话的完整历史记录的答案,并在用户关闭浏览器或导航离开网站时将其发布到我的api服务器。 (如果这不可能,我可以在每次导航时发布。)然后我想在用户主页上的“最近查看”页面列表中显示此历史记录。

1 个答案:

答案 0 :(得分:0)

首先,您不必干涉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__变量。