menu

Questions & Answers

Update Redux userData in React native

I am having an issue with Redux because i am very new in React-native Redux. i need to update my Redux data when i press the button.

My SignIn Screen Code:

 if (checkValid) {
        updateState({isLoading: true});
        try {
          const res = await actions.login({
            email,
            password,
          });
        } catch (error) {
          showError(error.msg);
          updateState({isLoading: false});
        }
      }

Redux Auth Code

import {LOGIN, SIGNUP} from '../../config/urls';
import {
  apiPost,
  clearUserData,
  setUserData,
  refreshUserData,
} from '../../utils/utils';
import {showError, showSuccess} from '../../utils/helperFunction';
import store from '../store';
import types from '../types';

const {dispatch} = store;

export const saveUserData = data => {
  dispatch({
    type: types.LOGIN,
    payload: data,
  });
};
export function login(data) {
  return new Promise((resolve, reject) => {
    return apiPost(LOGIN, data)
      .then(res => {
        if (res.code == 400) {
          showError(res.message);
        } else if (res.code == 200) {
          showSuccess(res.message);
          setUserData(res.results).then(() => {
            resolve(res);
            saveUserData(res.results);
          });
          return;
        }
        resolve(res);
      })
      .catch(error => {
        reject(error);
      });
  });
}
export function signup(data) {
  return apiPost(SIGNUP, data);
}
export function logout() {
  dispatch({type: types.CLEAR_REDUX_STATE});
  showSuccess('User has been Logout successfully');
  clearUserData();
}

export function Update() {
  dispatch({type: types.UPDATE_REDUX_STATE});
  showSuccess('Data Updated successfully');
  refreshUserData();
}

my Reducer code

import types from '../types';

const initial_state = {
  userData: {},
  is_verify: false,
  customer_first_time_login: false,
};

export default function (state = initial_state, action) {
  switch (action.type) {
    case types.LOGIN:
      const data = action.payload;
      return {userData: data};
    case types.UPDATE_REDUX_STATE:
      const updateData = action.payload;
      return {userData: updateData};
    default:
      return {...state};
  }
}

My utils

import axios from 'axios';
import AsyncStorage from '@react-native-async-storage/async-storage';
import store from '../redux/store';
import types from '../redux/types';
import {saveUserData} from '../redux/actions/auth';
import {showError} from './helperFunction';

const {dispatch, getState} = store;

export async function getHeaders() {
  let userData = await AsyncStorage.getItem('userData');
  if (userData) {
    userData = JSON.parse(userData);
    return {
      authorization: `${userData.access_token}`,
    };
  }
  return {};
}

export async function apiReq(
  endPoint,
  data,
  method,
  headers,
  requestOptions = {},
) {
  return new Promise(async (res, rej) => {
    const getTokenHeader = await getHeaders();
    headers = {
      ...getTokenHeader,
      ...headers,
    };

    if (method === 'get' || method === 'delete') {
      data = {
        ...requestOptions,
        ...data,
        headers,
      };
    }
    axios[method](endPoint, data, {headers})
      .then(result => {
        const {data} = result;
        if (data.status === false) {
          return rej(data);
        }
        return res(data);
      })
      .catch(error => {
        if (error && error.response && error.response.status === 401) {
          clearUserData();
          dispatch({
            type: types.CLEAR_REDUX_STATE,
            payload: {},
          });
          dispatch({
            type: types.NO_INTERNET,
            payload: {internetConnection: true},
          });
        }
        if (error && error.response && error.response.data) {
          if (!error.response.data.message) {
            return rej({
              ...error.response.data,
              msg: error.response.data.message || 'Network Error',
            });
          }
          return rej(error.response.data);
        } else {
          return rej({message: 'Network Error', msg: 'Network Error'});
        }
        return rej(error);
      });
  });
}

export function apiPost(endPoint, data, headers = {}) {
  return apiReq(endPoint, data, 'post', headers);
}

export function apiDelete(endPoint, data, headers = {}) {
  return apiReq(endPoint, data, 'delete', headers);
}

export function apiGet(endPoint, data, headers = {}, requestOptions) {
  return apiReq(endPoint, data, 'get', headers, requestOptions);
}

export function apiPut(endPoint, data, headers = {}) {
  return apiReq(endPoint, data, 'put', headers);
}

export function setItem(key, data) {
  data = JSON.stringify(data);
  return AsyncStorage.setItem(key, data);
}

export function getItem(key) {
  return new Promise((resolve, reject) => {
    AsyncStorage.getItem(key).then(data => {
      resolve(JSON.parse(data));
    });
  });
}

export function removeItem(key) {
  return AsyncStorage.removeItem(key);
}

export function clearAsyncStorate(key) {
  return AsyncStorage.clear();
}

export function setUserData(data) {
  data = JSON.stringify(data);
  return AsyncStorage.setItem('userData', data);
}

export async function getUserData() {
  return new Promise((resolve, reject) => {
    AsyncStorage.getItem('userData').then(data => {
      resolve(JSON.parse(data));
    });
  });
}
  
export async function refreshUserData(endPoint, data = null, headers = {}) {
  return axios
    .get(endPoint)
    .then(res => {
      //comment below code to overcome the error
      AsyncStorage.setItem('userData', JSON.stringify(user));
      setUserData(res.data);
      setUserData(res.data).then(() => {
        saveUserData(res.data);
      });
      return res;
    })
    .catch(error => {
      showError('Something went wrong');
    });
}
export async function clearUserData() {
  return AsyncStorage.removeItem('userData');
}


Now , i need to navigate the user to FirstTimeLogin screen when a user SignIn Successfully then a user can enter detail after entering detail user navigate to Home screen.

i have made separate stack for every navigation like AuthStack, MainStack and FristTimeLoginStack. so my question is when a user signIn successfully it navigate automatically to FirstTimeLogin but then when a user enter details in FirstTimeLogin and press button then it will not navigate to MainScreen that means Redux state not update just like it was updated when a user SignIn

Route Screen:

export default function Routes() {
  const userData = useSelector(state => state.auth.userData);
  let showscreen;
  
if (userData != null && userData.access_token != null) {
    if (userData.type == 'doctor') {
      if (userData.doctor_detail == null) {
        showscreen = [DoctorFTL(Stack)];
      } else {
        showscreen = [DoctorStack(Stack)];
      }
    }
  } else {
    showscreen = [AuthStack(Stack)];
  }

  return (
    <NavigationContainer>
      <Stack.Navigator screenOptions={{headerShown: false}}>
        {showscreen}
      </Stack.Navigator>
    </NavigationContainer>
  );
}
Answers(1) :

First you have to look the documentation of Redux because you said you are very new with Redux. Redux Documentation

and this link will help you to solve your problem. Solution link 1 Solution Link 2