1*e650bfb3S猫头猫import React, {ReactNode, useEffect, useRef} from 'react'; 2*e650bfb3S猫头猫import {StyleSheet, View} from 'react-native'; 3*e650bfb3S猫头猫import {atom, useAtomValue, useSetAtom} from 'jotai'; 4*e650bfb3S猫头猫 5*e650bfb3S猫头猫interface IPortalNode { 6*e650bfb3S猫头猫 key: string | null; 7*e650bfb3S猫头猫 children: ReactNode; 8*e650bfb3S猫头猫} 9*e650bfb3S猫头猫 10*e650bfb3S猫头猫const portalsAtom = atom<IPortalNode[]>([]); 11*e650bfb3S猫头猫 12*e650bfb3S猫头猫interface IPortalProps { 13*e650bfb3S猫头猫 children: ReactNode; 14*e650bfb3S猫头猫} 15*e650bfb3S猫头猫export default function Portal(props: IPortalProps) { 16*e650bfb3S猫头猫 const {children} = props; 17*e650bfb3S猫头猫 18*e650bfb3S猫头猫 const keyRef = useRef<string | null>(null); 19*e650bfb3S猫头猫 const setPortalsAtoms = useSetAtom(portalsAtom); 20*e650bfb3S猫头猫 21*e650bfb3S猫头猫 useEffect(() => { 22*e650bfb3S猫头猫 if (!keyRef.current) { 23*e650bfb3S猫头猫 // mount 24*e650bfb3S猫头猫 keyRef.current = Math.random().toString().slice(2); 25*e650bfb3S猫头猫 // console.log("MOUNT!", keyRef.current); 26*e650bfb3S猫头猫 setPortalsAtoms(portals => [ 27*e650bfb3S猫头猫 ...portals, 28*e650bfb3S猫头猫 {key: keyRef.current, children}, 29*e650bfb3S猫头猫 ]); 30*e650bfb3S猫头猫 } else { 31*e650bfb3S猫头猫 // update 32*e650bfb3S猫头猫 // console.log("UPDATE!", keyRef.current); 33*e650bfb3S猫头猫 setPortalsAtoms(portals => 34*e650bfb3S猫头猫 portals.map(it => 35*e650bfb3S猫头猫 it.key === keyRef.current ? {...it, children} : it, 36*e650bfb3S猫头猫 ), 37*e650bfb3S猫头猫 ); 38*e650bfb3S猫头猫 } 39*e650bfb3S猫头猫 }, [children]); 40*e650bfb3S猫头猫 41*e650bfb3S猫头猫 useEffect(() => { 42*e650bfb3S猫头猫 return () => { 43*e650bfb3S猫头猫 if (keyRef.current) { 44*e650bfb3S猫头猫 // console.log("UNMOUNT!", keyRef.current); 45*e650bfb3S猫头猫 setPortalsAtoms(portals => 46*e650bfb3S猫头猫 portals.filter(it => it.key !== keyRef.current), 47*e650bfb3S猫头猫 ); 48*e650bfb3S猫头猫 } 49*e650bfb3S猫头猫 }; 50*e650bfb3S猫头猫 }, []); 51*e650bfb3S猫头猫 52*e650bfb3S猫头猫 return null; 53*e650bfb3S猫头猫} 54*e650bfb3S猫头猫 55*e650bfb3S猫头猫export function PortalHost() { 56*e650bfb3S猫头猫 const portals = useAtomValue(portalsAtom); 57*e650bfb3S猫头猫 58*e650bfb3S猫头猫 return ( 59*e650bfb3S猫头猫 <> 60*e650bfb3S猫头猫 {portals.map(({key, children}) => ( 61*e650bfb3S猫头猫 <View 62*e650bfb3S猫头猫 key={key} 63*e650bfb3S猫头猫 collapsable={false} 64*e650bfb3S猫头猫 pointerEvents="box-none" 65*e650bfb3S猫头猫 style={StyleSheet.absoluteFill}> 66*e650bfb3S猫头猫 {children} 67*e650bfb3S猫头猫 </View> 68*e650bfb3S猫头猫 ))} 69*e650bfb3S猫头猫 </> 70*e650bfb3S猫头猫 ); 71*e650bfb3S猫头猫} 72