Reputation:
I've been doing some tests about changing a parent state property affecting directly with a new child re-render.
Using onMouseEnter/onMouseLeave methods of a parent to change "isMouseOver" state --> Affects to child.
Using useHover hook implemented using parent ref and event listener --> Affects to child
Using css Hover --> Doesn't affect to child
The problem is that parent "isMouseOver" state or "isHovered" shouldn't affect to child because it's not a child prop.
In child, I'm passing as a props "top" and "left", both setted in child styles, calculating a new top.
For each parent hover, child handleTop is triggered, giving me to undersantd that child is re-rendered for each state change of parent but in my head it has no logic because it should not re-render thanks to the virtual dom, so maybe is due the way of setting child style.
CODE:
PARENT
export default function App() {
const [isMouseOver, setIsMouseOver] = useState<boolean>(false);
const [elementRef, isHovered] = useHover();
const handleMouseOver = (isMouseOver: boolean): void => {
setIsMouseOver(isMouseOver);
};
return (
<div className={styles.App}>
<div
className={
isMouseOver
? `${styles.element} ${styles.element___isMouseOver}`
: styles.element
}
onMouseEnter={() => handleMouseOver(true)}
onMouseLeave={() => handleMouseOver(false)}
>
{/* <div ref={elementRef} className={styles.element}> */}
{/* <div className={styles.element}> */}
<PopOverComponent top={0} left={200} />
</div>
</div>
);
}
CHILD:
interface PopOverComponentProps {
top: number;
left: number;
}
export default function PopOverComponent({ top, left }: PopOverComponentProps) {
useEffect(() => {
console.log("top changes", top);
}, [top]);
const handleTop = (): number => {
const newTop = top + 25;
console.log("handleTop is triggered", newTop);
return newTop;
};
return (
<div style={{ top: handleTop(), left: left }} className={styles.popOver} />
);
}
Thank you very much in advance
Upvotes: 1
Views: 1262
Reputation: 3347
You can use React.memo()
for avoiding re-rendering stuff in react component. Avoiding React component re-renders with React.memo
Example :
interface PopOverComponentProps {
top: number;
left: number;
}
const PopOverComponent = React.memo(({ top, left }: PopOverComponentProps) => {
useEffect(() => {
console.log("top changes", top);
}, [top]);
const handleTop = (): number => {
const newTop = top + 25;
console.log("handleTop is triggered", newTop);
return newTop;
};
return (
<div style={{ top: handleTop(), left: left }} className={styles.popOver} />
);
})
export default PopOverComponent
Upvotes: 1