GOAL: Display the ToolkitArea only when the "#toolkitArea" has children
PROBLEM: I can't count the current amount of children inside the ToolkitArea for some reason
WHAT I DID SO FAR:
I have a component "Toolbar" and i want it to be displayed when Buttons are added via ReactPortal.
My current approach is having a UseEffect triggered inside the toolkitArea, checking for the amount of childrens inside the area.
import { faEyeSlash, faEye } from '@fortawesome/free-solid-svg-icons'
import ToolkitButton from './ToolkitButton'
import { useState } from 'react'
export interface ToolkitAreaProps {
children?: React.ReactNode
}
const ToolkitArea = ({ children }:ToolkitAreaProps) => {
const [visible, setVisible] = useState<boolean>(true)
const [isEmpty, setEmpty] = useState<boolean>(false)
const toolkit = useRef<HTMLDivElement>(null)
useEffect(() => {
const toolkitArea = (document.getElementById('toolkitArea') as HTMLDivElement)
console.log(toolkitArea.children, '', toolkit.current?.children, toolkit.current?.children.length)
if(toolkitArea.children.length > 0)
setEmpty(false)
else setEmpty(true)
}, [toolkit])
return <div className="fixed bottom-6 w-full h-16 z-40 px-8 md:pl-32 md:pr-16 flex">
<div className={`-ml-4 md:-ml-12 rounded-md w-16 h-16 bg-indigo-700 flex items-center justify-center shadow shadow-black shadow-md ${(visible || isEmpty) ? 'invisible' : 'visible'}`}>
<ToolkitButton icon={faEye} onClick={() => setVisible(true)} tooltip={'Show Toolbar'}/>
</div>
<div className={`h-full mx-auto bg-indigo-700 w-fit max-w-full rounded-md shadow shadow-black shadow-md py-2 flex px-4 overflow-x-auto md:overflow-x-visible ${(visible || isEmpty) ? 'invisible' : 'visible'}`}>
<ToolkitButton icon={faEyeSlash} onClick={() => setVisible(false)} className="-order-1" tooltip={'Toggle Toolbar'}/>
<div ref={toolkit} className={'w-fit flex gap-4 h-full pl-4'} id={'toolkitArea'}>
</div>
</div>
</div>
}
export default ToolkitArea
The output in the browser looks like this:

It says the children.length is 0, even when there are 5 elements displayed.
I have no clue what is responsible for this behavior. I can only imagine, the Buttons are added after the useEffect triggers, and the console.log inside the browser is adapted.
How can I achieve my goal, to only display the whole toolkitArea, when there are children inside the toolkitArea?
In general, React is not going to re-render your
ToolkitAreacomponent when the portal contents change, so theuseEffecthook won't be triggered. Even if it did, you may not be able to depend on the rendering order to have an accurate view of how many children the#toolkitAreaportal contains.I would suggest using some slightly heavy machinery in the form of the HTML5
MutationObserver, and run a callback in yourToolkitAreawhenever there's a change to the contents of the#toolkitAreadiv.You can wrap the necessary logic in a hook:
Sandbox
The hook returns a value
isEmptywhich you can then use in your component (note the use of a callback ref for#toolkitAreainstead of the ref object):