Redux: Opinions/examples of how to do backend persistence?

后端 未结 2 600
后悔当初
后悔当初 2021-01-30 02:21

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 kno

2条回答
  •  小鲜肉
    小鲜肉 (楼主)
    2021-01-30 02:49

    Definitely persist the state of your reducers!

    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.

    Example: persist one reducer's state to a server

    We'll start with three extra action types:

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

    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.

    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
    };
    

    (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!)

    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
      }
    }
    

    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!

提交回复
热议问题