Redux:如何进行后端持久化的意见/示例?

问题描述:

我想知道使用 Redux 的人是如何实现后端持久性的.特别是,您是将操作"存储在数据库中还是仅存储应用程序的最后一个已知状态?

I am wondering how folks using Redux are approaching their backend persistence. Particularly, are you storing the "actions" in a database or are you only storing the last known state of the application?

如果您要存储操作,是否只是从服务器请求它们,然后在给定页面加载时重放所有这些操作?对于有很多操作的大型应用程序,这难道不会导致一些性能问题吗?

If you are storing the actions, are you simply requesting them from the server, then replaying all of them when a given page loads? Couldn't this lead to some performance issues with a large scale app where there are lots of actions?

如果您只存储当前状态",那么当客户端上发生操作时,您实际上如何在任何给定时间持久化此状态?

If you are storing just the "current state", how are you actually persisting this state at any given time as actions happen on a client?

有没有人有一些关于如何将 redux reducer 连接到后端存储 api 的代码示例?

Does anyone have some code examples of how they are connecting the redux reducers to backend storage apis?

我知道这是一个非常这取决于您的应用程序"类型的问题,但我只是在这里思考一些想法并试图了解这种无状态"架构如何在全栈中工作感觉.

I know this is a very "it depends on your app" type question, but I'm just pondering some ideas here and trying to get a feel for how this sort of "stateless" architecture could work in a full-stack sense.

谢谢大家.

绝对保持减速器的状态!

如果您改为持久化一系列操作,您将永远无法在前端修改您的操作,而无需在 prod 数据库中摆弄.

If you persisted a sequence of actions instead, you wouldn't ever be able to modify your actions in your frontend without fiddling around inside your prod database.

示例:将一个 reducer 的状态持久化到服务器

我们将从三种额外的操作类型开始:

We'll start with three extra action types:

// actions: 'SAVE', 'SAVE_SUCCESS', 'SAVE_ERROR'

我使用 redux-thunk 进行异步服务器调用:这意味着一个动作创建者函数可以调度 额外操作并检查当前状态.

I use redux-thunk to do async server calls: it means that one action creator function can dispatch extra actions and inspect the current state.

save 动作创建者立即分派一个动作(这样你就可以显示一个微调器,或者在你的 UI 中禁用一个保存"按钮).然后在 POST 请求完成后分派 SAVE_SUCCESSSAVE_ERROR 操作.

The save action creator dispatches one action immediately (so that you can show a spinner, or disable a 'save' button in your UI). It then dispatches SAVE_SUCCESS or a SAVE_ERROR actions once the POST request has finished.

var actionCreators = {
  save: () => {
    return (dispatch, getState) => {
      var currentState = getState();
      var interestingBits = extractInterestingBitsFromState(currentState);

      dispatch({type: 'SAVE'});

      window.fetch(someUrl, {
        method: 'POST',
        body: JSON.stringify(interestingBits)
      })
      .then(checkStatus) // from https://github.com/github/fetch#handling-http-error-statuses
      .then((response) => response.json())
      .then((json) => dispatch actionCreators.saveSuccess(json.someResponseValue))
      .catch((error) =>
        console.error(error)
        dispatch actionCreators.saveError(error)
      );
    }
  },

  saveSuccess: (someResponseValue) => return {type: 'SAVE_SUCCESS', someResponseValue},

  saveError: (error) => return {type: 'SAVE_ERROR', error},

  // other real actions here
};

(注意 $.ajax 完全可以代替 window.fetch 的东西,我只是不想为一个函数加载整个 jQuery!)

(N.B. $.ajax would totally work in place of the window.fetch stuff, I just prefer not to load the whole of jQuery for one function!)

reducer 只跟踪任何未完成的服务器请求.

The reducer just keeps track of any outstanding server request.

function reducer(state, action) {
  switch (action.type) {
    case 'SAVE':
      return Object.assign {}, state, {savePending: true, saveSucceeded: null, saveError: null}
      break;
    case 'SAVE_SUCCESS':
      return Object.assign {}, state, {savePending: false, saveSucceeded: true, saveError: false}
      break;
    case 'SAVE_ERROR': 
      return Object.assign {}, state, {savePending: false, saveSucceeded: false, saveError: true}
      break;

    // real actions handled here
  }
}

你可能想要对从服务器返回的 someResponseValue 做一些事情 - 也许它是一个新创建的实体的 id 等等.

You'll probably want to do something with the someResponseValue that came back from the server - maybe it's an id of a newly created entity etc etc.

我希望这会有所帮助,到目前为止对我来说效果很好!

I hope this helps, it's worked nicely so far for me!