useSelector causes multiple re-renders
Asked Answered
E

1

5

When using react-devtools it tells me that the reason my root component re-renderd was because hooks changed?

when I remove any useSelectors, my root component renders only once, when enabled it renders 6 times.

what are some guesses as to why this is happening?

import {
  /// Data State Constants...
  SET_USER_DATA,
  SET_BADGE_COUNT,
} from "../Actions/gameState";

const initialState = {
  /// Data state...
  userData: [],
  badgeCount: 0,
};

export default function gameState(state = initialState, action) {
  const { type, payload } = action || {};
  switch (type) {
    /////////////////////////
    /// Data state Reducers...
    /////////////////////////
    case SET_USER_DATA: {
      return { ...state, userData: payload };
    }
    case SET_BADGE_COUNT: {
      return { ...state, badgeCount: payload };
    }

    default:
      return state;
  }
}
Edan answered 2/10, 2020 at 21:47 Comment(6)
There is no way we can tell what's going on without seeing the code, my suggestion is to try to reproduce the problem on snacks.expo.ioRagamuffin
Maybe you are changing/re-assigning the property, which you are selecting with useSelectors, after every render and the change is causing the component to re-render. Unfortunately, I can't help you properly, without seeing any code snippets.Collegiate
I am using logger so I would see those changes as they happen but no properties are changing.Edan
list your component and reducers, so we can take a look at the code. it's hard to guess what could be doing it without seeing at least the reducer.Glimp
as far as component goes. there is nothing special happening. I grab state from redux like this { someState } = useSelector(state=>state.myState). and for the reducer it looks like this: ( I just posted it on the OP )Edan
Make sure you test it on a production build as hooks are called twice on dev builds anywayDishrag
A
10

Ok, the thing is: the useSelector compare the new value with the old one with a strict ===. You can either call one useSelector per field or implement the shallowEqual from react-redux:

const someState = useSelector(state=>state.myState.someState, shallowEqual)

Here the documentation: https://react-redux.js.org/next/api/hooks#equality-comparisons-and-updates

Albemarle answered 6/10, 2020 at 2:0 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.