import ReactDom from 'react-dom'
import { useMemoizedFn, useUnmount } from 'ahooks'
import { Block } from '@tarojs/components'
import Taro, { useRouter } from '@tarojs/taro'
import React, { useLayoutEffect, useRef } from 'react'
type RootPortalProps = {
portalId: string
children: React.ReactElement
pageRouter?: ReturnType<typeof useRouter>
}
const RootPortal: React.FC<RootPortalProps> = ({ children, portalId, pageRouter }): React.ReactElement => {
const _router = useRouter()
const currentPageRef = useRef<Taro.Page>()
const router = pageRouter || _router
const getCurrentPage = useMemoizedFn(() => {
const pages = Taro.getCurrentPages()
const currentRoute = router.path.slice(1)
return pages.find(page => {
return page.route === currentRoute && page.$taroParams.$taroTimestamp == router.params.$taroTimestamp
})
})
useLayoutEffect(() => {
const currentPage = currentPageRef.current || getCurrentPage()
if (!currentPage) {
console.error('未获取到当前页面实例', {
pages: Taro.getCurrentPages(),
router
})
return
}
currentPageRef.current = currentPage
const root = document.getElementById(currentPage.$taroPath)
const _portalId = `${root?.uid}_${portalId}`
let portal = document.getElementById(_portalId)
if (root) {
if (!portal) {
portal = document.createElement('view')
portal.id = _portalId
root.appendChild(portal)
}
ReactDom.render(children, portal)
}
}, [children, getCurrentPage, portalId, router])
useUnmount(() => {
if (currentPageRef.current) {
const root = document.getElementById(currentPageRef.current!.$taroPath)
const _portalId = `${root?.uid}_${portalId}`
const portal = document.getElementById(_portalId)
if (root && portal) {
ReactDom.unmountComponentAtNode(portal)
}
}
})
return <Block/>
}
export default RootPortal