How to make the constant that is storing the value from redux store using useSelect() to update immediately after dispatch an action without re rendering in React Native

How to make the constant that is storing the value from redux store using useSelect() to update immediately after dispatch an action without re rendering in React Native
0

I am building a mobile app and I’m using Django REST Framework as a backend. And I am also using Redux. One of the API that I am using is to validate an OTP code. If the OTP code is matched, then I am retuning with the response from the server if this is a new user or not. If it’s a new user then I’ll redirect it to a registration screen, if not then I’ll redirect it to the login screen, this is my problem.

I am storing the response of the server in variable named isNewUser in redux store. Then, I am accessing it Inside my component with useSelector. When I click on the button after I entered then OTP code, I dispatch two actions. First the one to validate the OTP. The second is either will be a dispatch for Login or dispatch for registration action, this is depends on the variable isNewUser which I am getting from redux store.

The problem is that, when I dispatch the first action, which is validation of the OTP and storing of the isNewUser variable, the value of this variable is not updated in my component until the next render, so I can’t dispatch the second action until I click the button again so that the value of the variable is updated.

So how to fix that? I don’t know if my implementation is correct or not or there is a better one.

Here is my code for the action, I didn’t write the code for login and register actions yet

export const validateOTP = (otp, mobileNum) => {
  return async dispatch => {
    const response = await fetch("http://localhost:8000/api/validate_otp", {
      method: "POST",
      headers: {
        Accept: "application/json",
        "Content-Type": "application/json"
      },
      body: JSON.stringify({
        otp: otp,
        mobile: mobileNum
      })
    });
    if (!response.ok) {
      const errorResData = await response.json();
      console.log(errorResData);
    }

    const resData = await response.json();
    if (resData.status === false) {
      throw new Error(resData.detail);
    } else {
      const isNewUser = resData.isNewUser;
      dispatch({
        type: VALIDATE_OTP,
        isNewUser: isNewUser
      });
    }
  };
};

Here is my code for the reducer:

import { VALIDATE_OTP } from "../actions/auth";

const initialState = {
  isNewUser: null
};

export default (state = initialState, action) => {
  switch (action.type) {
    case VALIDATE_OTP: {
      const isNewUserVal = action.isNewUser;
      return {
        ...state,
        isNewUser: isNewUserVal
      };
    }
  }
  return state;
};

Here is a sample code from the React Native component:

const CodeEntryScreen = props => {
  const dispatch = useDispatch();
  const isNewUser = useSelector(state => state.auth.isNewUser)
  const [error, setError] = useState();


  useEffect(() => {
    if (error) {
      Alert.alert("An Error Occurred", error, [{ text: "Okay" }]);
    }
  }, [error]);

  const validateOTPHandler = async () => {
    setError(null);
    try {
      await dispatch(authActions.validateOTP(otp, mobileNum));
      console.log(isNewUser)
     if(isNewUser) {
        // dispatch resgister action
      }
      else {
        // dispatch  login action 
      }
    } catch (err) {
      setError(err.message);
    }
  };