React Redux store state update process after saving to database

My questions is a conceptual one and based on the issue outlined in this post: React Redux capture updated store state after updating database. I don’t think any code is needed to understand or be able to answer it. But if not it is at the link above.

I think I might have missed a small detail about the react/redux state update process following an action that changes the back-end data that a state variable reflects. My question is: When I dispatch a save action, should I then also be dispatching a request to update any state that depends on that underlying data?

So for example, right now the way I’m thinking about it and implementing my code is as follows:

  1. app starts and ParentComponent loads and dispatches GET_DATA on componentDidMount which initializes state variable data which is reflected on ParentComponent in a table
  2. when a link is clicked on ParentComponent, ParentComponent renders ChildComponent which is a react-modal popup that displays elements of data so it can be updated
  3. there is and Save and Close button on ChildComponent; when you click the button, SAVE_DATA is dispatched and the changes to data that are made on ChildComponent get saved to the database
  4. THIS is where my question arises… at this point should I also be calling GET_DATA to dispatch the process of “refreshing” data in my state? Would this be the right way to handle saving data to a database when using redux so that all components that rely on data get updated?

Note: What I’m currently doing is that after step 3, I am simply triggering a refresh function in ParentComponent so that it rerenders and hence reflects data in state. The epiphany I just had is that there is no way for data in state to reflect the new saved data because GET_DATA has not been dispatched after saving and rerendering the component does not trigger GET_DATA.

Are my assumptions correct? Should I be calling GET_DATA somewhere else in my ParentComponent like ComponentWillReceiveProps? The issue I had here is that maybe I’m doing something wrong, but it triggers an endless loop. Somehow though I feel that is the only place where I can address my need to dispatch GET_DATA after the local ParentComponent state is changed by setting refresh (a ParentComponent state variable) to true.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

I think it would benefit you to refactor your actions a bit to take advantage of the action/middleware/reducer pattern.

You would have an action GET_TRANSACTIONS, that would take your year param. Your transactionsMiddleware would respond to the GET_TRANSACTIONS action by making your fetch request and would dispatch GET_TRANSACTIONS_SUCCESS with the respond data on success. You transactions reducer would then process the data into your store.

actions
export const getTransactions = year => {
  return {
    type: "GET_TRANSACTIONS",
    year
  };
};

export const getTransactionsSuccess = payload => {
  return {
    type: "GET_TRANSACTIONS_SUCCESS",
    payload
  };
};

middleware
function getTransactions(year) {
  fetch().then(response => dispatch(actions.getTransactionsSuccess(response.data));
}

reducer
const getTransactionsSuccess = (state, action) => {
  return Object.assign({}, state, newStuffFromActionPayload);
}

You would also have an action SAVE_TRANSACTIONS, which would be what your button would dispatch, along with the data to save. Your transactionsMiddleware would respond to the action by dispatching the update request. Your API would return the data from the updated record.

This is where you would have the middleware dispatch a follow-up action. It could be your getTransactions action, but it’d be even better to dispatch an action that your reducer would respond to by merging in the new data to your store.

actions
export const updateTransaction = payload => {
  return {
    type: "UPDATE_TRANSACTION",
    payload
  };
};

export const updateTransactionSuccess = payload => {
  return {
    type: "UPDATE_TRANSACTION_SUCCESS",
    payload
  };
};

middleware
function updateTransaction(transUpdate) {
  fetch().then(response => dispatch(actions.updateTransactionSuccess(response.data))
}

reducer
const updateTransactionSuccess = (state, action) => {
  find the record in the state, update it with data from action.payload
  return Object.assign({}, state, updatedRecord);
}

If everything is set up correctly, it should trigger an update on your parent when it detects the change in the store. You avoid making two API calls for every save as well.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x