Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React and Redux toolkit - reject after promise

I'm working on a React Native app. I have a signup screen which has a button, onclick:

const handleClick = (country: string, number: string): void => {
    dispatch(registerUser({ country, number }))
      .then(function (response) {
        console.log("here", response);
        navigation.navigate(AuthRoutes.Confirm);
      })
      .catch(function (e) {
        console.log('rejected', e);
      });
  };

The registerUser function:

export const registerUser = createAsyncThunk(
    'user/register',
    async ({ country, number }: loginDataType, { rejectWithValue }) => {
        try {
            const response = await bdzApi.post('/register', { country, number });
            return response.data;
        } catch (err) {
            console.log(err);
            return rejectWithValue(err.message);
        }
    },
);

I have one of my extraReducers that is indeed called, proving that it's effectively rejected.

.addCase(registerUser.rejected, (state, {meta,payload,error }) => {
    state.loginState = 'denied';
    console.log(`nope : ${JSON.stringify(payload)}`);
})

But the signup component gets processed normally, logging "here" and navigating to the Confirm screen. Why is that?

like image 484
Jeremy Belolo Avatar asked Sep 11 '25 07:09

Jeremy Belolo


1 Answers

A thunk created with createAsyncThunk will always resolve but if you want to catch it in the function that dispatches the thunk you have to use unwrapResults.

The thunks generated by createAsyncThunk will always return a resolved promise with either the fulfilled action object or rejected action object inside, as appropriate.

The calling logic may wish to treat these actions as if they were the original promise contents. Redux Toolkit exports an unwrapResult function that can be used to extract the payload of a fulfilled action or to throw either the error or, if available, payload created by rejectWithValue from a rejected action:

import { unwrapResult } from '@reduxjs/toolkit'

// in the component
const onClick = () => {
  dispatch(fetchUserById(userId))
    .then(unwrapResult)
    .then(originalPromiseResult => {})
    .catch(rejectedValueOrSerializedError => {})
}
like image 80
HMR Avatar answered Sep 13 '25 22:09

HMR