React v16.13.0
日本語版サイトでは英語版ブログに定期的に追従しつつ、2020 年以降の記事を随時翻訳しています。
このブログはアーカイブされています。最新の記事は ja.react.dev/blog でご覧ください。
本日、React 16.13.0 をリリースします。このリリースには、バグ修正と、今後のメジャーリリースに備えるための新しい非推奨の警告が含まれています。
新たな警告
レンダー中のいくつかの更新に関する警告
React コンポーネントは、レンダー中に他のコンポーネントに副作用を起こしてはいけません。
レンダー中に setState
を呼び出すことはサポートされていますが同じコンポーネントに対してのみ可能です。別のコンポーネントのレンダー中に setState
を呼び出すと、警告が表示されるようになりました。
Warning: Cannot update a component from inside the function body of a different component.
この警告は、意図しない状態変更によって引き起こされるアプリケーションのバグを見つけるのに役立ちます。レンダーの結果として他のコンポーネントの状態を意図的に変更したいという稀なケースでは、setState
呼び出しを useEffect
にラップすることができます。
スタイルルールが矛盾している場合の警告
ある CSS プロパティの長い記法と短い記法を同時に含む style
を動的に適用する場合、特定の更新の組み合わせにより、スタイリングの一貫性が失われることがあります。例えば、以下のようになります。
<div style={toggle ?
{ background: 'blue', backgroundColor: 'red' } :
{ backgroundColor: 'red' }
}>
...
</div>
この <div>
は toggle
の値に関係なく常に背景色が赤になると思われるかもしれません。しかし、このデモを見てわかるように、toggle
の値を true
と false
の間で切り替えると、背景色は red
から始まり、その後 transparent
と blue
の間で交互に切り替わります。
React は、スタイルルールの競合を検出し、警告をログに記録するようになりました。この問題を修正するには、同一の CSS プロパティの短い記法と長い記法のバージョンを style
プロパティ内で混在させないようにしてください。
一部の非推奨 string ref に関する注意点
String ref(文字列形式の ref)は古いレガシー API であり、既に勧められておらず、将来的に正式に非推奨となる予定です。
<Button ref="myRef" />
(String ref と異なり、一般的な ref 自体は完全にサポートされ続けますので混同しないようにしてください)
将来的には、string ref からの移行を自動化するスクリプト (“codemod”) を提供する予定です。しかし、まれに自動移行できないケースがあります。このリリースでは、非推奨化に先立ち、そのようなケースにのみ警告を追加しています。
例えば、レンダープロップパターンと一緒に string ref を使用した場合に発生します。
class ClassWithRenderProp extends React.Component {
componentDidMount() {
doSomething(this.refs.myRef);
}
render() {
return this.props.children();
}
}
class ClassParent extends React.Component {
render() {
return (
<ClassWithRenderProp>
{() => <Button ref="myRef" />}
</ClassWithRenderProp>
);
}
}
このようなコードはしばしばバグを示します(ref は ClassParent
で利用できると思われるかもしれませんが、代わりに ClassWithRenderProp
に置かれてしまいます)。
このようなコードはお持ちでない可能性が高いでしょう。もしそのようなコードがあって、それが意図的なものであれば、代わりに React.createRef()
を使うよう変更してください:
class ClassWithRenderProp extends React.Component {
myRef = React.createRef();
componentDidMount() {
doSomething(this.myRef.current);
}
render() {
return this.props.children(this.myRef);
}
}
class ClassParent extends React.Component {
render() {
return (
<ClassWithRenderProp>
{myRef => <Button ref={myRef} />}
</ClassWithRenderProp>
);
}
}
補足
この警告を見るためには、Babel プラグインとして babel-plugin-transform-react-jsx-self がインストールされている必要があります。これは開発モードでのみ有効にする必要があります。
Create React App を使っているか、Babel 7 以降で “react” プリセットを使っている場合、既にデフォルトでこのプラグインはインストールされています。
React.createFactory
の非推奨化
React.createFactory
は React 要素を作成するためのレガシーのヘルパです。このリリースでは、このメソッドに非推奨の警告が追加されています。これは将来のメジャーバージョンで削除される予定です。
React.createFactory
の使用法を通常の JSX で置き換えてください。代わりに、この 1 行ヘルパをコピー&ペーストするか、ライブラリとして公開することもできます。
let createFactory = type => React.createElement.bind(null, type);
全く同じことをしています。
ReactDOM.unstable_createPortal
の非推奨化、ReactDOM.createPortal
に変更を
React 16 がリリースされたとき、createPortal
は公式にサポートされる API になりました。
しかし、unstable_createPortal
を採用している少数のライブラリが動作するように、unstable_createPortal
をサポートされたエイリアスとして残していました。今後この不安定なエイリアスは非推奨とします。unstable_createPortal
の代わりに createPortal
を直接使ってください。これは全く同じシグネチャを持っています。
その他の改良事項
hydration の警告におけるコンポーネントスタック
React は開発者向け警告にコンポーネントスタックを追加し、開発者がバグを特定してプログラムをデバッグできるようにしています。今回のリリースでは、以前はコンポーネントスタックが存在しなかった多くの開発者向け警告に、それが追加されました。例として、以前のバージョンにあったこのハイドレーション警告を考えてみましょう。
コードとともにエラーを指摘していますが、どこにエラーが存在しているのか、次に何をすればいいのかが明確ではありません。このリリースでは、この警告にコンポーネントスタックが追加され、以下のようになりました。
これにより、問題がどこにあるのかが明確になり、より早くバグの場所を特定して修正することができます。
注目すべきバグ修正
このリリースには、他にもいくつかの注目すべき改善点が含まれています。
- Strict 開発モードでは、React はライフサイクルメソッドを 2 回呼び出し、好ましくない副作用の可能性を洗い出すようにしています。このリリースでは、その動作を
shouldComponentUpdate
に追加しています。これは、shouldComponentUpdate
に副作用がない限り、ほとんどのコードには影響しないはずです。これを修正するには、副作用のあるコードをcomponentDidUpdate
に移動してください。 - Strict 開発モードでは、レガシーコンテクスト API の使用に関する警告には、警告のトリガとなったコンポーネントのスタックが含まれていませんでした。このリリースでは、欠けていたスタックが警告に追加されます。
- 無効な(disabled の)
<button>
要素に対してonMouseEnter
がトリガされないようになりました。 - ReactDOM は v16 を公開して以来、
version
のエクスポートがありませんでした。このリリースではそれが改めて追加されました。アプリケーションロジックでの使用はお勧めしませんが、同じページ上の ReactDOM のバージョン不一致や複数バージョンに関わる問題をデバッグする際に便利です。
これらの問題やその他の問題を解決してくれた貢献者に感謝します。完全な changelog は下記を参照してください。
インストール
React
React v16.13.0 は npm レジストリで利用可能です。
Yarn で React 16 をインストールするには、下記を実行します:
yarn add react@^16.13.0 react-dom@^16.13.0
npm で React 16 をインストールするには、下記を実行します:
npm install --save react@^16.13.0 react-dom@^16.13.0
また、CDN 経由で React の UMD ビルドも提供しています:
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
詳細なインストール方法については、ドキュメントを参照してください。
変更履歴
React
- Warn when a string ref is used in a manner that’s not amenable to a future codemod (@lunaruan in #17864)
- Deprecate
React.createFactory()
(@trueadm in #17878)
React DOM
- Warn when changes in
style
may cause an unexpected collision (@sophiebits in #14181, #18002) - Warn when a function component is updated during another component’s render phase (@acdlite in #17099)
- Deprecate
unstable_createPortal
(@trueadm in #17880) - Fix
onMouseEnter
being fired on disabled buttons (@AlfredoGJ in #17675) - Call
shouldComponentUpdate
twice when developing inStrictMode
(@bvaughn in #17942) - Add
version
property to ReactDOM (@ealush in #15780) - Don’t call
toString()
ofdangerouslySetInnerHTML
(@sebmarkbage in #17773) - Show component stacks in more warnings (@gaearon in #17922, #17586)
Concurrent Mode (Experimental)
- Warn for problematic usages of
ReactDOM.createRoot()
(@trueadm in #17937) - Remove
ReactDOM.createRoot()
callback params and added warnings on usage (@bvaughn in #17916) - Don’t group Idle/Offscreen work with other work (@sebmarkbage in #17456)
- Adjust
SuspenseList
CPU bound heuristic (@sebmarkbage in #17455) - Add missing event plugin priorities (@trueadm in #17914)
- Fix
isPending
only being true when transitioning from inside an input event (@acdlite in #17382) - Fix
React.memo
components dropping updates when interrupted by a higher priority update (@acdlite in #18091) - Don’t warn when suspending at the wrong priority (@gaearon in #17971)
- Fix a bug with rebasing updates (@acdlite and @sebmarkbage in #17560, #17510, #17483, #17480)