Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where is a good to call actions for fail and success in react-redux

I have a question about redux.

Now, I'm building my mobile app following redux advanced tutorial.

The tutorial says that you have to create 3 actions each 1 function so I have created 3 actions for sign-in function like below:

requestSignIn
requestSignInSuccess
requestSignInFailure

However, I don't understand where the app should call them from.

Now, in my app, the app calls requestSignInSuccess and requestSignInFailure in requestSignIn.

This is my action code:

export const REQUEST_SIGN_IN = 'REQUEST_SIGN_IN';
export const REQUEST_SIGN_IN_FAILURE = 'REQUEST_SIGN_IN_FAILURE';
export const REQUEST_SIGN_IN_SUCCESS = 'REQUEST_SIGN_IN_SUCCESS';

import firebase from 'react-native-firebase';

export function requestSignIn() {
  // start sign in function
  firebase.auth().signInWithEmailAndPassword(EMAIL, PASSWORD)
    .then(response => {
      // success, so call requestSignInSuccess() to change state
      requestSignInSuccess(response.user);
    })
    .catch(error => {
      // fail, so call requestSignInFailure() to change state
      requestSignInFailure(error);
    })

}

function requestSignInSuccess(user) {
  // save user info into state in reducer
  return {
    type: 'REQUEST_SIGN_IN_SUCCESS'
    payload: user
  }
}

function requestSignInFailure(error) {
  // save error message into state in reducer
  return {
    type: 'REQUEST_SIGN_IN_FAILURE'
    payload: error
  }
}

[Questions]

  • Am I following the redux tutorial correctly? (The app calls requestSignInFailure and requestSignInSuccess in requestSignIn function, is it good?)
  • If I want the app to have isLoading flag into state, which action should change the flag?
like image 336
Satoru Kikuchi Avatar asked Sep 20 '25 07:09

Satoru Kikuchi


1 Answers

Let me try to answer one by one your questions.

Am I following the redux tutorial correctly?

Yes, you are on the right track, just few steps missing. The below explanation is for class based components.

Technically if you created actions - just like above in your question - then what you need to do is dispatching them in the component in order to use.

  1. Firstly need to dispatch the actions in mapDispatchToProps.
  2. Then need to connect the component - to call requestSignIn action - with the Redux store.
  3. Pass the created mapDispatchToProps to connect as the second parameter.

Please find the following example below:

import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';

// ... other imports

class YourComponent extends React.Component {
     constructor (props) {
         super(props);
     }

     // ... component code
     // ... obviously this is just an example component for representation

     render() {
         return (
             <>
                 <a onClick={props.requestSignIn()}>Request Sign In</a>
             </>
         )
     }
}

const mapDispatchToProps = dispatch => {
    return bindActionCreators({ requestSignIn }, dispatch);
};


export default connect(null, mapDispatchToProps)(YourComponent);

If I want the app to have isLoading flag into state, which action should change the flag?

I would create in the reducer a new property called isLoading just like below:

const initialState = {
    isLoading: false,
};

export default (state=initialState, action) => {
    switch(action.type) {
         case 'ENABLE_LOADING':
              return {
                   ...state,
                   isLoading: true,
              };

         case 'REQUEST_SIGN_IN_SUCCESS':
              return {
                   ...state,
                   isLoading: false,
              };

         case 'REQUEST_SIGN_IN_FAILURE':
              return {
                   ...state,
                   isLoading: false,
              };

         // ... other actions
    }
}

In your requestSignIn action need to trigger ENABLE_LOADING once you start fetching the data one line before firebase.auth().signInWithEmailAndPassword(EMAIL, PASSWORD) then it will hopefully work for you. Just like how you did with REQUEST_SIGN_IN_SUCCESS and REQUEST_SIGN_IN_FAILURE.

To access the reducer's properties you need to use mapStateToProps further.

In functional component case you need to use useDispatch to call the created actions:

This hook returns a reference to the dispatch function from the Redux store. You may use it to dispatch actions as needed.

And to access the data from the store there is a hook called useSelector:

Allows you to extract data from the Redux store state, using a selector function.

Quick summary:

If you are looking for a fully working example with useSelector and useDispatch in a functional component then take a look at this git repository:

https://github.com/norbitrial/react-redux-loading-data-example

In the repository you will find a nice representation of a fake API call which loads data into a table with a loader indicator, just like what you need from your question.

In case of further interest in more details please find the below links which are pretty useful:

  1. Connect: Dispatching Actions with mapDispatchToProps
  2. Connect: Extracting Data with mapStateToProps
  3. Dispatching actions with useDispatch() for functional component
  4. Extract data with useSelector() for functional component

I hope this helps, let me know if you need further clarification.

like image 93
norbitrial Avatar answered Sep 22 '25 21:09

norbitrial