Search code examples
reactjsreduxreact-redux

react redux useselector causing rerender


I am using react and redux toolkit with redux-persist. When making an http request in useEffect it causes the component to re-render infinite times even the data doesn't change, so the problem is in useSelector, I have even tried shallowEqual function and also without strict mode, but it doesn't work.

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

const cartReducer = createSlice({
  name: 'cart',
  initialState: {
    ids: [],
  },
  reducers: {
    cartAction: (state, action) => {
      const checkId = state.ids.findIndex((item) => item === action.payload);
      if (checkId === -1) {
        state.ids = [...state.ids, action.payload];
      }
    },
  },
});
import { configureStore } from '@reduxjs/toolkit';
import { combineReducers } from 'redux';
import storage from 'redux-persist/lib/storage';
import { persistReducer } from 'redux-persist';
import {
  persistStore,
  FLUSH,
  PAUSE,
  REGISTER,
  PERSIST,
  REHYDRATE,
  PURGE,
} from 'redux-persist';

import cartReducer from '../redux/cartRedux';

const reducers = combineReducers({
  cart: cartReducer,
});

const persistConfig = {
  key: 'cartItems',
  storage,
};

const persistedReducer = persistReducer(persistConfig, reducers);

const store = configureStore({
  reducer: persistedReducer,
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({
      serializableCheck: {
        ignoredActions: [REGISTER, FLUSH, PAUSE, PERSIST, REHYDRATE, PURGE],
      },
    }),
});

let persistors = persistStore(store);
import { useSelector, shallowEqual } from 'react-redux';

let cartItemsId = useSelector((state) => state.cart.ids, shallowEqual);
const [loading, setLoading] = useState(false);
const [products, setProducts] = useState([]);

  useEffect(() => {
    const getCartProductsById = async () => {
      setLoading(true); 
      return await axios
        .post('/getMultipleProducts', cartItemsId)
        .then((response) => {
          setLoading(false);
          setProducts(response.data);
          console.log(products);
        })
        .catch((error) => {
          setLoading(false);
          console.log(error);
        });
    };
    getCartProductsById();
  }, [cartItemsId,products]);


Solution

  • This has nothing to do with Redux at all.

    Your infinite loop is caused by setProducts(response.data); in combination with the dependency array.

    Your useEffect has products as a dependency, so if products changes it will make a new request to the server - and after that request set those products will be a new object, even if that object has the same contents. So the dependency changes, which triggers a new cycle of the useEffect.