Skip to content

Commit

Permalink
refactor(portal): remove useRef from portal component (#39792)
Browse files Browse the repository at this point in the history
The PR is similar to #39791.

Currently, `<Portal />` saves the container in a ref (with initial value as `null`). The update of the ref happens during the `useEffect`, after creating the corresponding HTMLElement. However, `<Portal />` has to use `forceUpdate` since mutating a ref will not cause the component to update.
The PR fixes that by saving the container of the `Portal` in a state, so no more `forceUpdate`.
  • Loading branch information
SukkaW committed Aug 21, 2022
1 parent ea7efcb commit 05b621a
Showing 1 changed file with 10 additions and 12 deletions.
22 changes: 10 additions & 12 deletions packages/next/client/portal/index.tsx
@@ -1,24 +1,22 @@
import React from 'react'
import { useEffect, useState } from 'react'
import { createPortal } from 'react-dom'

type PortalProps = {
children: React.ReactNode
type: string
}

export const Portal: React.FC<PortalProps> = ({ children, type }) => {
let portalNode = React.useRef<HTMLElement | null>(null)
let [, forceUpdate] = React.useState<{}>()
React.useEffect(() => {
portalNode.current = document.createElement(type)
document.body.appendChild(portalNode.current)
forceUpdate({})
export const Portal = ({ children, type }: PortalProps) => {
const [portalNode, setPortalNode] = useState<HTMLElement | null>(null)

useEffect(() => {
const element = document.createElement(type)
document.body.appendChild(element)
setPortalNode(element)
return () => {
if (portalNode.current) {
document.body.removeChild(portalNode.current)
}
document.body.removeChild(element)
}
}, [type])

return portalNode.current ? createPortal(children, portalNode.current) : null
return portalNode ? createPortal(children, portalNode) : null
}

0 comments on commit 05b621a

Please sign in to comment.