在React + Redux中加载静态常量

时间:2017-07-21 00:33:09

标签: reactjs redux serverside-rendering

我正在为我的React-Redux应用程序使用服务器端渲染。我希望在应用程序启动时加载一些常量,例如具有相应ID的城市列表:

[ 
  {
      name: "London",
      id: 1
  }
  ...
]

我认为最好将这些数据放入服务器端的store,然后按http://redux.js.org/docs/recipes/ServerRendering.html

的建议使用window.__INITIAL_STATE__将其提供给客户端

这个常量是只读的,我想只是为了数据规范化目的而预加载它们。例如,稍后我可以检索具有城市ID的用户列表,而不是具有城市名称的用户:{name: "Alex", cities: [1,2]}

问题是,如果我把它们存入商店,那么我就不得不为这个常量创建reducer,否则我会收到这个错误:

  

传递给preloadedState参数的意外键“cities”   createStore。预计会找到一个已知的减速器键:   “颜色”。意外的密钥将被忽略。

所以我正在寻找一些优雅的方法来处理这种情况。

目前我有2个想法如何处理它:

  1. 创建空的reducer,它总是会返回默认状态

    export const cities = (state = [], action={ type: null }) => {
        return state
    }
    
  2. Send from server initial actions with payloads, and execute them on client at startup

    // server.js
    window.INITIAL_ACTIONS = [
      { type: "REQUEST_LOGIN_SUCCESS", user: {userId, userName, userEmail, etc} },
      { type: "REQUEST_CITIES_SUCCESS", [..listOfCities] },
    ]
    
  3. 在我的client-index.js中,在创建商店后立即发送这些操作:

    //client-index.js
    window.INITIAL_ACTIONS.forEach(store.dispatch)
    

    那么,我的方法之一是好的吗?或者您可能知道其他更优雅的解决方案吗?

    感谢。

1 个答案:

答案 0 :(得分:2)

我们使用虚拟“设置”减速器做类似的事情。即。

const rootReducer = combineReducers({
  ...
  settings: (state = {}) => state,
  ...
});

这为我们提供了一个存储我们所有应用配置的便利位置。

请确保以相同的方式键入初始状态。即。

window.__INITIAL_STATE__ = {
  ...
  settings: { ... },
  ...
};

有些人可能会反对这种做法,但我认为这是合理的。虽然settings可能是不变的,但它仍然是状态。它符合单个状态对象的redux实践。 (此外,未来可能会出现设置状态切片是动态的并且需要“真正的”缩减器。)

相关问题