import { memo , useCallback , useEffect , useMemo , useRef } from 'react' ; import { nanoid } from 'nanoid/non-secure' ; import { usePortal } from '../../hooks/usePortal' ; import type { PortalProps } from './types' ; const PortalComponent = ( { name : _providedName , hostName , handleOnMount : _providedHandleOnMount , handleOnUnmount : _providedHandleOnUnmount , handleOnUpdate : _providedHandleOnUpdate , children , } ) => { const { addPortal : addUpdatePortal , removePortal } = usePortal ( hostName ) ; const name = useMemo ( ( ) => _providedName || nanoid ( ) , [ _providedName ] ) ; const handleOnMountRef = useRef < Function > ( ) ; const handleOnUnmountRef = useRef < Function > ( ) ; const handleOnUpdateRef = useRef < Function > ( ) ; const handleOnMount = useCallback ( ( ) => { if ( _providedHandleOnMount ) { _providedHandleOnMount ( ( ) => addUpdatePortal ( name , children ) ) ; } else { addUpdatePortal ( name , children ) ; } } , [ _providedHandleOnMount , addUpdatePortal ] ) ; handleOnMountRef . current = handleOnMount ; const handleOnUnmount = useCallback ( ( ) => { if ( _providedHandleOnUnmount ) { _providedHandleOnUnmount ( ( ) => removePortal ( name ) ) ; } else { removePortal ( name ) ; } } , [ _providedHandleOnUnmount , removePortal ] ) ; handleOnUnmountRef . current = handleOnUnmount ; const handleOnUpdate = useCallback ( ( ) => { if ( _providedHandleOnUpdate ) { _providedHandleOnUpdate ( ( ) => addUpdatePortal ( name , children ) ) ; } else { addUpdatePortal ( name , children ) ; } } , [ _providedHandleOnUpdate , addUpdatePortal , children ] ) ; handleOnUpdateRef . current = handleOnUpdate ; useEffect ( ( ) => { handleOnMountRef . current ?. ( ) ; return ( ) => { handleOnUnmountRef . current ?. ( ) ; handleOnMountRef . current = undefined ; handleOnUnmountRef . current = undefined ; handleOnUpdateRef . current = undefined ; } ; } , [ ] ) ; useEffect ( ( ) => { handleOnUpdateRef . current ?. ( ) ; } , [ children ] ) ; return null ; } ; export const Portal = memo ( PortalComponent ) ; Portal . displayName = 'Portal' ;