title: React Native - How to store auth token and navigate to other screen after login?
body: <p>I am a newbie in react native, I am creating one react native application with redux. I am only on the login page. Currently, I implemented redux successfully and getting response from API when login credentials are right and getting error if credentials are wrong.</p>
  
  <p>Basically, I have 2 questions in which I am stuck.</p>
  
  <ol>
  <li>How to navigate to new screen when login is successfully?</li>
  <li>Where to store auth token globally so I can identify user is logged in or not on any page?</li>
  </ol>
  
  <p>Below are the response i get when login is successfully </p>
  
  <p><a href="https://i.stack.imgur.com/AAs1z.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/AAs1z.png" alt="enter image description here"></a></p>
  
  <p>Below are the code for my files.
  screens/Login.js</p>
  
  <pre><code>import React, { Component } from 'react';
  import { connect } from 'react-redux';
  import { LoginComponent } from '../components/LoginComponent';
  // import { Button } from 'react-native-material-design';
  import { View, Text, TextInput, StatusBar, KeyboardAvoidingView } from 'react-native';
  import { Button } from 'react-native-elements';
  import PropTypes from 'prop-types';
  import { connectAlert } from '../components/Alert';
  import { login, handleEmailChange, handlePasswordChange } from '../actions/user';
  
  
  class Login extends Component {
  
    static propTypes = {
      navigation: PropTypes.object,
      // dispatch: PropTypes.func,
      user: PropTypes.object,
      email: PropTypes.string,
      password: PropTypes.string,
      alertWithType: PropTypes.func,
      loginError: PropTypes.string
    }
    componentWillReceiveProps(nextProps) {
      // if (nextProps.loginError &amp;&amp; nextProps.loginError !== this.props.loginError) {
      if (nextProps.loginError ) {
          this.props.alertWithType("error", "Error occurred in login", nextProps.loginError)
      }
    }
    handleSubmit = () =&gt; {
      this.props.login(this.props.email, this.props.password)
    }
  
    handleChange = (type, e) =&gt; {
      if (type === "email"){
        this.props.dispatch(handleEmailChange(e))
      }
      else{
        this.props.dispatch(handlePasswordChange(e))
      }
    }
  
    render(){
      return(
        &lt;View style={{ flex: 1, justifyContent: 'center' }}&gt;
        &lt;StatusBar barStyle="default" translucent={false} /&gt;
        &lt;KeyboardAvoidingView behavior='padding'&gt;
          &lt;Text style={{textAlign: 'center', fontWeight: '800'}}&gt; AfterClix Login &lt;/Text&gt;
          &lt;TextInput  
                 autoCapitalize="none" 
                 onSubmitEditing={() =&gt; this.passwordInput.focus()} 
                 autoCorrect={false} 
                 keyboardType='email-address' 
                 returnKeyType="next" 
                 placeholder='Email' 
                //  onChangeText={event =&gt; this.handleChange("email",event)}
                onChangeText={this.props.changeEmailValue}
                 placeholderTextColor='rgb(65, 146, 244)'/&gt;
        &lt;TextInput    
                returnKeyType="go" 
                ref={(input)=&gt; this.passwordInput = input} 
                placeholder='Password' 
                placeholderTextColor='rgb(65, 146, 244)' 
                onChangeText={this.props.changePasswordValue}
                // onChangeText={event =&gt; this.handleChange("password",event)}
                secureTextEntry/&gt;
          &lt;Button raised title="Login" backgroundColor="rgb(65, 146, 244)" color="#FFFFFF" onPress={this.handleSubmit}/&gt;
        &lt;/KeyboardAvoidingView&gt;
      &lt;/View&gt;
      )
    }
  }
  const mapStateToProps = (state) =&gt; {
    return {
      // user: state.authentication.user
      email: state.user.email,
      password: state.user.password,
      loginError: state.user.error
    }
  }
  
  const mapDispatchToProps = dispatch =&gt; {
    return {
        changeEmailValue: (text) =&gt; dispatch({type: 'CHANGE_EMAIL_VALUE', text}),
        changePasswordValue: (text) =&gt; dispatch({type: 'CHANGE_PASSWORD_VALUE', text}),
        login: (email,password) =&gt; dispatch({type: 'LOGIN', email, password}),
    };
  };
  
  
  export default connect(mapStateToProps, mapDispatchToProps)(connectAlert(Login));
  </code></pre>
  
  <p>actions/user.js</p>
  
  <pre><code>export const LOGIN = "LOGIN";
  export const AUTHENTICATION_RESULT = "AUTHENTICATION_RESULT";
  export const AUTHENTICATION_ERROR = "AUTHENTICATION_ERROR";
  export const CHANGE_EMAIL_VALUE = "CHANGE_EMAIL_VALUE";
  export const CHANGE_PASSWORD_VALUE = "CHANGE_PASSWORD_VALUE";
  
  export const login = (email, password) =&gt; ({
    type: LOGIN,
    email: email,
    password: password
  })
  
  export const handleEmailChange = (value) =&gt; ({
    type: CHANGE_EMAIL_VALUE,
    email: value
  })
  
  export const handlePasswordChange = (value) =&gt; ({
    type: CHANGE_PASSWORD_VALUE,
    password: value
  })
  </code></pre>
  
  <p>reducers/user.js</p>
  
  <pre><code>import {LOGIN, AUTHENTICATION_RESULT, AUTHENTICATION_ERROR, CHANGE_EMAIL_VALUE, CHANGE_PASSWORD_VALUE} from '../actions/user'
  const initialState = {
    // user: {
    //   email: '',
    //   password: '',
    //   error: null,
    // }
      email: '',
      password: '',
      error: null,
  };
  
  const reducer = (state = initialState, action) =&gt; {
    switch (action.type) {
      case LOGIN: 
        return {
          ...state,
          email: state.email,
          password: state.password
        }
      case CHANGE_EMAIL_VALUE:    
        // return {...state, email: action.email };
        return {...state, email: action.text };
      case CHANGE_PASSWORD_VALUE:
        return {...state, password: action.text };
      case AUTHENTICATION_RESULT:
        console.log("Result", action.result.data)
        return {...state, email: action.result.data.user.email, password: action.result.data.user.password };
          // return {
          //   ...state,
          //   user: {
          //       ...state,
          //       [action.result.base]: {
          //           ...action.result,
          //       }
          //   }
        // }
      case AUTHENTICATION_ERROR:
        return {
            ...state,
            error: action.error,
        }
      default:
        return state;
    }
  }
  
  export default reducer;
  </code></pre>
  
  <p>config/saga.js</p>
  
  <pre><code>import { takeEvery, select, call, put } from 'redux-saga/effects';
  import { LOGIN, AUTHENTICATION_RESULT, AUTHENTICATION_ERROR } from '../actions/user';
  
  const authenticateUser = (email, password) =&gt; fetch('apiURL/oauth/token', {
    method: 'POST',
    headers: {
      Accept: 'application/json',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      email: email,
      password: password,
      grant_type: "password"
    }),
  });
  function* fetchUser(action){
      try{
        console.log("Email", action.email)
        console.log("Password", action.password)
        const response = yield call(authenticateUser, action.email, action.password)
        const result = yield response.json();
        if (result.error) {
            yield put({ type: AUTHENTICATION_ERROR, error: result.error });
        } else {
            yield put({ type: AUTHENTICATION_RESULT, result });
        }
      }
      catch (e) {
        yield put({ type: AUTHENTICATION_ERROR, error: e.message });
      }
  }
  export default function* rootSaga() {
      yield takeEvery(LOGIN, fetchUser);
  }
  </code></pre>