Reputation: 47
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
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