Closed5

React 18 upgrate メモ

Hi MORISHIGEHi MORISHIGE

React v18 へアップグレードする際のメモ

$ yarn add react@latest react-dom@latest
$ yarn add -D @types/react@latest @types/react-dom@latest
Hi MORISHIGEHi MORISHIGE

React v18からcreateRootの利用が推奨されるためエントリーファイルを書き換える。
https://github.com/reactwg/react-18/discussions/5

index.tsx
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import { App } from 'src/App';

const container = document.getElementById('root');

// typescripst環境だとcontainer要素がない場合がある旨のエラーが出るので存在しない場合はErrorをthrowさせておく
if (!container) throw new Error('Failed to find the root element');

const root = createRoot(container);

root.render(
  <StrictMode>
    <App />
  </StrictMode>,
);
Hi MORISHIGEHi MORISHIGE

The current testing environment is not configured to support act(…)

Test環境で上記エラーが出た場合はsetupファイルに下記を追加する。

globalThis.IS_REACT_ACT_ENVIRONMENT = true;
Hi MORISHIGEHi MORISHIGE

Viteのテンプレートが使っているこれが一番シンプルそう

import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import './index.css'

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
)

eslint ruleによっては一部除外の必要もあり。

// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
Hi MORISHIGEHi MORISHIGE

React18のStrictモードは冪等性を担保するために開発サーバー時にuseEffectに空配列を与えていても2度実行される。どうしても一度しか実行できない場合はuseRefを利用する。

https://github.com/reactwg/react-18/discussions/18#discussioncomment-795623

const didLogRef = useRef(false);

useEffect(() => {
  // In this case, whether we are mounting or remounting,
  // we use a ref so that we only log an impression once.
  if (didLogRef.current === false) {
    didLogRef.current = true;

    SomeTrackingAPI.logImpression();
  }
}, []);
このスクラップは2022/11/19にクローズされました