From 05b621aa9cf236bc2bc706a6076c310e68f1e30d Mon Sep 17 00:00:00 2001 From: Sukka Date: Sun, 21 Aug 2022 17:39:43 +0800 Subject: [PATCH] refactor(portal): remove useRef from portal component (#39792) The PR is similar to #39791. Currently, `` 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, `` 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`. --- packages/next/client/portal/index.tsx | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/packages/next/client/portal/index.tsx b/packages/next/client/portal/index.tsx index 7e38a485f46b..681bcab7bc79 100644 --- a/packages/next/client/portal/index.tsx +++ b/packages/next/client/portal/index.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import { useEffect, useState } from 'react' import { createPortal } from 'react-dom' type PortalProps = { @@ -6,19 +6,17 @@ type PortalProps = { type: string } -export const Portal: React.FC = ({ children, type }) => { - let portalNode = React.useRef(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(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 }