Search code examples
reactjsreduxredux-toolkit

State value not change when dispatch to another reduces in redux


I am building login system. I am having problem with store state value when I use Selector function. in my system, I want to get isSuccess, error, userInfo from store state values

/login/index.js

const userLogin = useSelector((state) => state.userLogin);
console.log(userLogin);
const { isSuccess, error, userInfo } = userLogin;

if error it will show error message on UI, otherwise if isSuccess it will show success message. isSuccess appears when post to api success (it mean user login success) and user data is dispatched to loginSuccess reduces else error value dispatched to loginFail reduces

/action/userAction.js

import {
loginSuccess,
loginFail,
} from "\~/redux/user/userLoginSlice";

export const login = (inputs) =\> async (dispatch) =\> {
try {
const {data} = await request.post("/auth/login", inputs);
dispatch(loginSuccess(data));
localStorage.setItem("userInfo", JSON.stringify(data));
} catch (error) {
console.log(error.response.data)
dispatch(loginFail(error.response.data))
}

. however instead of just getting isSuccess in loginSucces reduce, it also get error when previous login was loginFail console.log(userLogin). it should only show userInfo and isSuccess. anyone help me to solve this problem with . this is reduces

userLoginSlice.js



import { createSlice } from '@reduxjs/toolkit';


const userLoginSlice = createSlice({
    name: 'userInfo',
    initialState: {},
    reducers: {
        loginSuccess: (state, action) => {
            state.isSuccess = true;
            state.userInfo = action.payload;
        },
        loginFail: (state, action) => {
            state.error = action.payload
        },
    },
});

export const { loginSuccess, loginFail } = userLoginSlice.actions;

export default userLoginSlice.reducer;

and my reduce store

store.js

import { configureStore } from '@reduxjs/toolkit';

import productModalReducer from './product-modal/productModalSlice';
import cartItemsSlice from './cart/cartSlide';
import userLoginSlice from './user/userLoginSlice.js';
import userRegisterSlice from './user/userRegisterSlice.js';
import userUpdateSlice from './user/userUpdateSlice.js';

const userInfoFromStorage = localStorage.getItem('userInfo') ? JSON.parse(localStorage.getItem('userInfo')) : null;

const initialState = {
    userLogin: { userInfo: userInfoFromStorage },
};

export const store = configureStore({
    reducer: {
        productModal: productModalReducer,
        cartItems: cartItemsSlice,
        userLogin: userLoginSlice,
        userRegister: userRegisterSlice,
        userUpdate: userUpdateSlice,
    },
    preloadedState: initialState,
});

State value not change when dispatch to another reduces in redux


Solution

  • It seems that this could be because loginSuccess is only adding userInfo and isSuccess to the state but not omitting previous error.

    Perhaps try reset state value to exclude error in the reducer:

    const userLoginSlice = createSlice({
      name: "userInfo",
      initialState: {},
      reducers: {
        loginSuccess: (state, action) => {
          // 👇 Reset state to omit error message in loginSuccess
          state = { isSuccess: true, userInfo: action.payload };
        },
        loginFail: (state, action) => {
          // 👇 Could add "isSuccess: false, userInfo: null" if needed
          state = { error: action.payload };
        },
      },
    });
    

    Or return a state value instead of using Immer proxy state:

    const userLoginSlice = createSlice({
      name: "userInfo",
      initialState: {},
      reducers: {
        loginSuccess: (state, action) => {
          // 👇 Reset state to omit error message in loginSuccess
          return { isSuccess: true, userInfo: action.payload };
        },
        loginFail: (state, action) => {
          // 👇 Could add "isSuccess: false, userInfo: null" if needed
          return { error: action.payload };
        },
      },
    });