Can we cancel the api response when the router changes?

I use the same form and the same state in redux for adding and editing. When I call the api to get the data for editing, and we change our router to add a form before receiving a response. All form data will be automatically filled in to add an item, since I use the same state for adding and editing. Is there any way to prevent this?

my action creator:

fetchById: function (entity, id) { return function (dispatch) { dispatch(apiActions.apiRequest(entity)); return (apiUtil.fetchById(entity, id).then(function (response) { dispatch(apiActions.apiResponse(entity)); dispatch(actions.selectItem(entity, response.body)); } } } 

In response late, then selectItem is sent late. And when I open the form to add an element, then this form is filled with this data from the response.

+6
source share
2 answers

Thunks receive both dispatch and getState as arguments.

If you keep the current route somewhere in your state, you can check the API callback whether you stay on the same page with getState().routing.path or something like this, and return if it has changed since launch the API

If you do not keep the current route in a state, you can instead read this.context.router in your component (remember to define contextTypes to get it!) And pass it to the action creator. The action creator can then use router.isActive() to check if everyone was on the same path before and after the request.

Finally, you can simply not use the same state to edit and add an item. The state form may look like { drafts: { newItem: ..., 1: ..., 2: ... } } , and you can save the "add" form to drafts.newItem and save any form "change" with the corresponding identifier entities. Thus, they will never overwrite each other and, as a bonus, changes in progress can be saved, for example. if you click "Back" and then go back to the form (depending on whether you want this in your UX, of course).

+3
source

I saw this blog post the other day, and I think the second part describes what you are looking for. You do not necessarily want to cancel requests, but ignore the responses.

Basically, you want to create an external reducer that will track your asynchronous server requests with unique identifiers. Only if the request identifier is in the list, then allow it to sub-reducers.

When you switch the page, you want to delete this list of unique identifiers.

Raised directly from the blog:

 const initialState = []; function update(state = initialState, action) { const { seqId } = action; if (action.type === constants.UNLOAD) { return initialState; } else if (seqId) { let newState; if (action.status === 'start') { newState = [...state, seqId]; } else if (action.status === 'error' || action.status === 'done') { newState = state.filter(id => id !== seqId); } return newState; } return state; } 

and then restrict the sub-reducers:

 let store = createStore((state, action) => { if (action.seqId && (action.status === 'done' || action.status === 'error') && state && state.asyncRequests.indexOf(action.seqId) === -1) { return state; } return reducer(state, action); }); 

Big shout to James for that. A really nice solution and is very well explained in his blog post.

+1
source

All Articles