JavaScript
React

React Portalはセット先の中身が残る

ReactのPortalを便利に使っていたのですが、意外な動作をする場面がありました。


Portalとは

詳しくは別項に譲りますが、Reactのコンポーネントの一部を別なDOM位置にセットできる機能です。


renderしたときの挙動の違い

ふつうにReactDOM.render()でコンポーネントをセットすると、もともとセット先のDOM要素にあった中身は削除されます

一方で、ReactDOM.createPortal()としても、ポータルをセットする先のDOMにあった中身はそのまま残ります。この違いには要注意です。

See the Pen React Portal test by Jkr2255 (@jkr2255) on CodePen.


どうすればいいか

「中身をクリアしたい」という条件でPortalを使いたい場合、最初の1回だけクリアする必要があります。「コンストラクタでやればいい」と思われるかもしれませんが、React 17で計画されている非同期レンダリングでは、コンストラクタすら何度も実行されうるので、不適当となります。

ということで、クラスコンポーネントではポータルを生成していなければ中身をクリアした上でポータルを作る、関数コンポーネントではWeakMapで管理するなどの手段が必要かと思います。


外部リンク