0
votes

I am wondering if I understand the pattern of Redux-thunk async operations correctly, in React or React-Native , and how we can do user feedback on the status of operation.

I am feeling either I don't understand the pattern, or there are other pieces of the puzzle.

So, in my React-native application (but it could be for a React as well), I want to call an update REST call, which will return a promise. And in case of success or failure, I want to display a message accordingly to the user.

Without Redux-async, I just call the rest, and handle the promise.

callServiceUpdate(data).then(() => displaySuccessMessage())
.catch(() => displayErrorMessage());

In Redux training, when we do async, we just dispatch an action, and the action will do a call to the async operation.

so, in the action file where we define the actions:

// in file databaseActions.js

export function updateStatusAction(isSuccess, errorMessage) {
return {
    type: 'UPDATE_STATUS',
    isSuccess,
    errorMessage };
}

export function UpdateAction(data) {
   return (dispatch) => {
     callServiceUpdate(data)
         .then(() => dispatch(updateStatusAction(true)))
         .catch((error) => dispatch(updateStatusAction(false, error)));
}};

and dispatching the action will call the service.

and then we dispatch the updateStatusAction, which will update the redux state , and update back the components through props.

But then how to get the success result back to the user? Is it through props, and handling componentWillReceiveProps?

isn't that over-complicating ? Or there is a simpler way to give feedback for the user?

3

3 Answers

2
votes

FYI you don't need to return callServiceUpdate() in updateAction. As far as giving feedback, you can either have your component render certain elements depending on what props have been set or as you've mentioned override componentWillReceiveProps/componentDidReceiveProps.

You can also specify scenarios in which your component should update in shouldComponentUpdate to avoid undesirable re-renders. I wouldn't say that this is an overcomplicated approach.

0
votes

You need to dispatch an action containing your desired success result which will be consumed by a reducer which outputs a new state depending on your success result.

function todoApp(state, action) {
if (typeof state === 'UPDATE_STATUS') {
return { ...state, action.payload } // You can access this by connecting your components to the global redux store.
}
return state
}
0
votes

After I did some researches on this subject, and searched for how people are solving this.

I found the usual pattern of dealing with Ajax, is as I mentioned in my question. But , the feedback for the user of the ajax call status is happening in one place only in the UI, which is in the root component container, or any parent component container that contains all child components that do ajax calls.

If you need to read more about how to design the UI to fit the good React UI Design good practices then read about representational components and container components

The usual pattern in handling Ajax calls in React + Redux is as follows:

  1. Send an action that will indicate the query or Ajax call started.

  2. Send an action that will start the Ajax call.

  3. Upon receive the result from Ajax, either send an Action for SUCCESS or FAILURE.

these are example of such actions

{ type: 'FETCH_POSTS_REQUEST' }
{ type: 'FETCH_POSTS_FAILURE', error: 'Oops' }
{ type: 'FETCH_POSTS_SUCCESS', response: { ... } }

on Reducers side, you need three parts of the have a part of the Status to indicate an Ajax request is being running (to show a busy indicator)

The State in the store will looks something similar to this

frontend: {
      isFetching: true,
      didInvalidate: false,
      items: []
    },

And then in the root container, do handle the isFetching to render a busy indicator.

And do handle items to show the result, or show errors