Route change before action creator completes

2019-08-16 02:33发布

问题:

In my react-redux application, I have an action creator which makes 4 server calls, first three calls are made async and then last one waits on the response of 3rd call.

Lets us say someone changes the route before response of 3rd came, 4th call wont be made. How can I ensure this does not happen?

Either I should not allow route change until actioncreator has done its job (users won't like this). Or, I should allow 4th call to happen even if the route is changed, looks like a reasonable solution from users perspective. I don't know how to code any of the solution, please opine.

Note: Route change can happen from navigation bar on the top.

回答1:

Method 1 -

If you want to show a non dismissible overlay to the user while your API call is running, you can do so like this -

//You can pass a prop like isShown to toggle the visibility, Here Modal component is used from **react-bootstrap** library
//backdrop and keyboard false prop means it's non dismissible
<Modal className="loader" show={this.props.isShown} backdrop={false} keyboard={false}>
    <Modal.Body className="text-center">
      <div><img className="loader-image" src="https://d1ykm90fp7q29d.cloudfront.net/assets/images/misc/loader.gif"/>
      </div>
      <br/>
      <h2> Loader text </h2>
    </Modal.Body>
</Modal>

You can create a separate Modal component like above and import it where you want to use it. Visibility can be toggle by any state variable which is accessible in your api call.

Method 2 - Ideally, even if your route changes, it should not effect your action and action creators and your async api calls should run as it is. You may have not implemented the api calls properly. You can use redux saga like this -

Pseudo Code:

//Main saga
function* mainSaga(params){
  const [result1, result2, result3]  = yield all([
    call(apiCall1, params1), //function apiCall1 should call your Api1 
    call(apiCall2, params2),
    call(apiCall3And4, params3And4) //apiCall3And4 is another saga which is implemented below
  ])
}

//apiCall3And4 saga
function* apiCall3And4(params){
  const call3result = yield call(apiCall3, params3);
  if(call3Result != null){
    //call api 4
    yield call(apiCall4, params4);
  }
}


回答2:

You can choose one of this:

  • React Router (v4) supports preventing transitions
  • Full client-side React App will do background calculations by default (it's called state of application).

Also you could use server-side rendering to prefetch data from API.