Anon1223
Anon1223

Reputation: 47

React JS components rerendering despite callbacks when props are passed

In my react project, I set up callbacks to stop excessive re-renderings, because the data displayed there is fairly large, and there are a lot of different buttons that the user can click, all which would cause rerenderings.

The useCallback hooks work, and no rerenderings are called, unless I am also passing in props alongside the useCallback functions, in which case the child component is rerendered every time the user interacts with the app.

So for instance, if I create a child component like so :

<Dropdown
//props={{ cat, var }}
getLi={getLi}
getType={getType}
increment={increment}
/>

And inside the dropdown child I define cat and var as const cat = "" and const var = "10"

Then the component does not get rerendered when I click on the dropdown menu buttons inside the child component.

However, if I create the child component like this -

<Dropdown
props={{ cat, var }}
getLi={getLi}
getType={getType}
increment={increment}
/>

And then define cat and var as const {cat, var} = props

The callback functions do not work, and the childcomponent gets rerendered constantly.

I tried adding both of the variables in props to the list of dependancies in the callback function, which also did nothing.

Upvotes: 1

Views: 1463

Answers (1)

Nicholas Tower
Nicholas Tower

Reputation: 85032

props={{ cat, var }}

Every time this runs, it creates a new object. The object may have the same keys and values, but it's a new object. If you're using React.memo on the Dropdown, then it's going to do a === between the old object and the new object, see that they're different, and thus rerender.

If you want to skip renders, you need to make sure all your props pass a === check. So you can either memoize this object:

const example = useMemo(() => {
  return { cat, var }
}, [cat, var])

// ...
<Dropdown
  props={example}

Or split it into separate props, so each of them will have its own === check.

<Dropdown
  cat={cat}
  var={var}
  getLi={getLi}
  // ...

Upvotes: 1

Related Questions