I have the following code where changes on the parent component cause child element re - render. Basically the Menu component should be appear by right click on top of the placeholder tag but when it appears the whole parent component flickers. I used Usecallback with no luck. I tried useMemo but it doesn't accept any arguments. Since my callback functions are firing as a result of events, passing target of the event is important. Therefore I should pass the argument. I appreciate any suggestion.
const [menu, setMenu] = useState({isActive: false, position: undefined});
<div className='placeholder'
onClick={clickHandler}
onContextMenu={rightClickHandler}>
{menu.isActive && <Menu menu={menu} />}
{[props.entity].map(plc => {
let Content = place[props.entity];
if(Content) {
return <Content key={Math.random()} />
}
})}
</div>
const rightClickHandler = useCallback((e) => {
e.preventDefault();
const parentPosition = e.target.getBoundingClientRect();
const position = {
left: e.clientX - parentPosition.left,
top: e.clientY - parentPosition.top
};
setMenu(
{
isActive: (menu.isActive ? menu.isActive: !menu.isActive),
position: {
left: position.left,
top: position.top
}
}
);
}, []);
const clickHandler = useCallback((e) => {
setMenu({isActive: false, module: '', position: undefined});
}, []);
Remove Math.random()
It will reinforce the component to re render
const [menu, setMenu] = useState({isActive: false, position: undefined});
<div className='placeholder'
onClick={clickHandler}
onContextMenu={rightClickHandler}>
{menu.isActive && <Menu menu={menu} />}
{[props.entity].map((plc, i) => {
let Content = place[props.entity];
if(Content) {
return <Content key={'somethingElse' + i} />
}
})}
</div>
const rightClickHandler = useCallback((e) => {
e.preventDefault();
const parentPosition = e.target.getBoundingClientRect();
const position = {
left: e.clientX - parentPosition.left,
top: e.clientY - parentPosition.top
};
setMenu(
{
isActive: (menu.isActive ? menu.isActive: !menu.isActive),
position: {
left: position.left,
top: position.top
}
}
);
}, []);
const clickHandler = useCallback((e) => {
setMenu
({isActive: false, module: '', position: undefined});
}, []);