How to show and hide activityindicator from actions in react native redux?

4.1k views Asked by At

I want to show progress/activityindicator whenever I make an api call from my app, But I can't find the correct solution for this. I can show the activityindicator but I can't hide it from view. Here is my code:

StatusModal.js

constructor(props) {
 super(props)
 // set state with passed in props
 this.state = {
   message: props.error,
   hide: props.hide,
   animating: props.animating
 }
}

render() {  
 if(this.state.animating){
   return(
     <ActivityIndicator
       animating={true}
       size="small"
      />
   )
 }else{
   return(
     <View>
     </View>
   )
 }
}

and here is how I change the animating state

//show activity
Actions.statusModal({animating: true})

//hide activity
Actions.statusModal({animating: false})

and here is my scene structure:

<Scene key="modal" component={Modal} >
 <Scene key="root">
 <Scene key='login' component={Login} title='Login Page' hideNavBar={true} />
 </Scene>
 <Scene key="statusModal" component={StatusModal} />
</Scene>

How can I hide the activity indicator from actions?

1

There are 1 answers

1
Slowyn On BEST ANSWER

It's pretty common thing for applications to handle loading. The simplest way to handle it is create a separate reducer for this. E.g.:


    function appStateReducer(state = { loading: false }, action) {
        switch(action.type) {
          case "SET_LOADING":
            return { loading: action.payload };
          default:
            return { loading: false };
        }
    }

    ...
    const rootReducer = combineReducer(
       ...otherReducers,
       app: appStateReducer
    );
    ...

Later you can use it in your components.


...

    const mapStateToProps = (state) => ({
        loading: state.app.loading,
    });

    @connect(mapStateToProps)
    class MyScene extends Component {
    ...

    render() {
       const { loading } = this.props;
       if (loading) {
       return (
           
         );
        }
        return ;
    }

Dispatch action SET_LOADING in the start of query with true and dispatch SET_LOADING with false in the end or in case of error.

But one single state for handling loading isn't enough for big application. For example: you need to handle parallel queries to API and to show loader for every single query. Then you'll need such fields in other reducers.

By the way, you'll definitely meet the issue with async flow. I would recommend such middlewares as redux-thunk, redux-saga and redux-observable.

My favourite one is redux-saga. It's a very powerful way to control your async flow and all other side effects in your application.

I hope it helps.