0
votes

I have this function in

    export const authSlice = createSlice({
  name: "auth",
  initialState: {
    credentials: {},
    isLoading: false,
  },
  reducers: {
    isLoading: (state) => {
      state.isLoading = !state.isLoading;
    },
  },
  extraReducers: (builder) => {
    builder
      .addCase(signInByEmail.fulfilled, (state, action) => {
        state.credentials = action.payload;
      })
      .addCase(signInByEmail.rejected, (state, action) => {
        Alert.alert(
          "OOPS!",
          "Wrong Email or Password",
          [{ text: "Try Again" }],
          { cancelable: false }
        );
      })
      .addCase(signUpByEmail.pending, state => state.isLoading = true)
      .addCase(signUpByEmail.fulfilled, (state, action)=> {

      })
  },
});

its Giving me an error in state.isLoading = true

But if i do it like this

    export const authSlice = createSlice({
  name: "auth",
  initialState: {
    credentials: {},
    isLoading: false,
  },
  reducers: {
    isLoading: (state) => {
      state.isLoading = !state.isLoading;
    },
  },
  extraReducers: (builder) => {
    builder
      .addCase(signInByEmail.fulfilled, (state, action) => {
        state.credentials = action.payload;
      })
      .addCase(signInByEmail.rejected, (state, action) => {
        Alert.alert(
          "OOPS!",
          "Wrong Email or Password",
          [{ text: "Try Again" }],
          { cancelable: false }
        );
      })
      .addCase(signUpByEmail.pending, (state, action) => {
          state.isLoading = true
      })
      .addCase(signUpByEmail.fulfilled, (state, action)=> {

      })
  },
});

After i broke into another line i get no error. What an I missing.

This is the error im getting just in case.

No overload matches this call. Overload 1 of 2, '(actionCreator: AsyncThunkPendingActionCreator<{ email: string; password: string; }>, reducer: CaseReducer<{ credentials: {}; isLoading: boolean; }, PayloadAction<undefined, string, { ...; }, never>>): ActionReducerMapBuilder<...>', gave the following error. Type 'boolean' is not assignable to type 'void | { credentials: {}; isLoading: boolean; }'. Overload 2 of 2, '(type: string, reducer: CaseReducer<{ credentials: {}; isLoading: boolean; }, Action>):

1

1 Answers

1
votes

The error has to do with what is being returned from your reducer. In the case that works, you aren't returning anything. It is a void function which mutates the draft state.

.addCase(signUpByEmail.pending, (state, action) => {
     state.isLoading = true
})

There is an alternative syntax which is also acceptable where you return a new state as a replacement for the current state, ie.

.addCase(signUpByEmail.pending, (state, action) => ({...state, isLoading: true}))

But the state that you return must be a complete state object.

Type 'boolean' is not assignable to type 'void | { credentials: {}; isLoading: boolean; }'

The error says that the two valid return types are void as in the first example or the complete state { credentials: {}; isLoading: boolean; } as in the second.

The error also says that you are returning boolean. This is because arrow functions without braces always return something.

This function a mutates the object and returns void / undefined:

const a = (num: {n: number}): void => { num.n = 1; }

But when we don't have the curly braces {}, we return the result of the expression. We both mutate the object and return 1.

const b = (num: {n: number}): number => num.n = 1;

Try it out!

In short, the braces are necessary to prevent you from returning a value when assigning state.isLoading = true. Without them, you return true which is not a valid return type for a reducer.