0
votes

I am trying to put a condition on my button with the help of my redux state, the code is as follows

{showotpbox == true ? (
            <IonItem>
              <IonLabel position="stacked">OTP</IonLabel>
              <IonInput
                type="number"
                onIonChange={(e) => handleChangeOtp(String(e.detail.value))}
              />
            </IonItem>
          ) : (
            ""
          )}

where showotpbox is a react hook state, which initally is set to false, now after clicking a button that says "GET OTP" i dispatch an action

let data = { email };
await dispatch(requestOTP(data));

which then after succes dispatch a type that changes state of a reducer

export const requestOTP = (data: any) => (dispatch: any) => {
  console.log('requesting')
  dispatch({ type: "LOADING", payload: true });
  console.log(data);
  axios
    .post("http://localhost:4000/request_otp", data)
    .then((res) => {
      console.log(res)
      if (res.data.status == 200) {
        dispatch({type:'SHOW_OTP_BOX'})
      } 
    })
    .catch((err) => {
      dispatch({ type: "LOADING", payload: false });
      dispatch(errorActions());
    });
};

which in turn updates a state in my modal reducer

case 'SHOW_OTP_BOX':
return {...state,showotpbox:true}

but i see that action is somehow async cause when i look at this function

const modal = useSelector((state: RootState) => {
return {show: state.modal.showotpbox };
});
const getotp = async () => {
    let data = { email };
    await dispatch(requestOTP(data));
    console.log(modal.show);
    if (modal.show == true) {
      setshowotpbox(true);
    }
  };

"console.log(modal.show);" still gives me false, although the state has been update to true and that's why my input box doesn't render

i try to use async await here in my getotp function to wait for the action to be completed but that doesn't work it seems

1
I think you may want to review the react documentation on component lifecycle. Can you provide a Minimal, Complete, and Reproducible code example? What is modal.modal.showotpbox, where does it come from, and what is supposedly updating it?Drew Reese
have updated last section a little...see if it helps? @DrewReeseRatnabh kumar rai
store update is async you cannot get correct value there. As you are already updating value in store for showotpbox:true, you can directly read value from store. It will work you don't need to wait.deepak
Right, ok. Yeah, your "state" modal from the render cycle the action was dispatched encloses a "copy" of modal for the life of that function execution, it won't update in the middle of the function. Is the expected behavior to setshowotpbox(true); when modal.show becomes true? Have you tried an useEffect for this "reactive" effect?Drew Reese
hmm wells store.subscribe worked for me !!Ratnabh kumar rai

1 Answers

1
votes

As dispatch is async you have to handle store updation as soon as it updates callback function will be called.

var store = createStore(); // Redux store if it is created it should return store else it should create store and return
var storeUnsubscribe = store.subscribe(handleStoreChange);
function handleStoreChange() {
   console.log(state.modal.show);
    if (state.modal.show == true) {
      setshowotpbox(true);
    }
}
const modal = useSelector((state: RootState) => {
  return {show: state.modal.showotpbox };
});
const getotp = async () => {
    let data = { email };
    await dispatch(requestOTP(data));
};