react-helmetの代わりにreact-helmet-asyncを使う

2021.06.24

吉川@広島です。

HTMLのメタ情報を書き換えるためにreact-helmetを使おうとしたのですが、 Warning: Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. という警告が発生しました。

結論から言うとreact-helmet-asyncを使うことで解決しました。

環境

  • typescript 4.3.2
  • react 17.0.2
  • react-helmet 6.1.0
  • react-helmet-async 1.0.9

react-helmet

nfl/react-helmet

import React from 'react'
import ReactDOM from 'react-dom'
import { Helmet } from 'react-helmet'
import { App } from './app'

ReactDOM.render(
  <React.StrictMode>
    <Helmet>
      <title>My Title</title>
    </Helmet>
    <App />
  </React.StrictMode>,
  document.querySelector('#root')
)

このようにreact-helmetを使うとGoogle ChromeのDeveloper Consoleに以下の警告が出力されました。

react_devtools_backend.js:2560 Warning: Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. See https://reactjs.org/link/unsafe-component-lifecycles for details.

* Move code with side effects to componentDidMount, and set initial state in the constructor.

Please update the following components: SideEffect(NullComponent2)

読んでみると「UNSAFE_componentWillMountを使うのはStrictモードでは非推奨だよ、バグを生む可能性があるよ」ということが言われています。

このへんのキーワードでググってみると次のissueを発見しました。

Stop using UNSAFE_componentWillMount #548

どうやらreact-helmetが依存しているreact-side-effectの中でUNSAFE_componentWillMountを使用してしまっているようです。

Uses legacy componentWillMount #54

componentWillMountについて

Update on Async Rendering

React v16.3以降、componentWillMountは「(特に非同期レンダリングが有効になった場合に)バグが発生しやすいコーディング手法を助長する傾向がある」として非推奨のライフサイクルになっているようです。

react-helmet-async

staylor/react-helmet-async

こちらは

This package is a fork of React Helmet.

とあるように、react-helmetからフォークしたリポジトリです。

import React from 'react'
import ReactDOM from 'react-dom'
import { Helmet, HelmetProvider } from 'react-helmet-async'
import { App } from './app'

ReactDOM.render(
  <React.StrictMode>
    <HelmetProvider>
      <Helmet>
        <title>My Title</title>
      </Helmet>
      <App />
    </HelmetProvider>
  </React.StrictMode>,
  document.querySelector('#root')
)

react-helmetと比較して、HelmetProviderでラップする以外は使い心地は変わらなさそうに思いました。

これで冒頭の警告は解消されました。

npm trendsを確認すると、最近はreact-helmetよりreact-helmet-asyncの方がダウンロードされているようです。

react-helmet vs react-helmet-async

npm-trends

まとめ

Reactアプリケーションでメタ情報を書き換えたい場合、今後はreact-helmet-asyncが第一選択肢となりそうです。

以上、参考になれば幸いです。