We want to hear from you!Take our 2021 Community Survey!
このサイトの更新は終了しました。ja.react.dev へ

React v17.0

October 20, 2020 by Dan Abramov and Rachel Nabors
日本語版サイト (ja.reactjs.org) のブログセクションへの記事掲載には英語版サイトと比べてタイムラグがあります。 最新のブログ記事は英語版でご確認ください。
日本語版サイトでは英語版ブログに定期的に追従しつつ、2020 年以降の記事を随時翻訳しています。

このブログはアーカイブされています。最新の記事は ja.react.dev/blog でご覧ください。

本日、React 17 をリリースします! React 17 リリースの役割や含まれている変更点については React 17 RC のブログ記事で詳しく述べてあります。この記事はそちらの短いサマリとなりますので、RC の記事を既に読んでいる場合は、本記事は飛ばして構いません。

新機能 “なし”

この React 17 リリースは普段のリリースと異なっており、開発者向けの新機能が何も追加されていません。代わりに、このリリースは React 自体のアップグレードを簡単にすることに焦点を当てています。

具体的には React 17 は、あるバージョンの React で管理されるツリー内に、別のバージョンの React で管理されるツリーをより安全に埋め込めるようにするための、「踏み台」となるリリースとなっています。

また、他のテクノロジによって構築されているアプリ内に React を埋め込むことも容易になります。

段階的なアップグレード

React 17 は段階的な React のアップグレードを可能にします。React 15 から 16 に(そして今回は React 16 から 17 に)アップグレードする場合、普通はアプリ全体をまとめてアップグレードします。これは多くのアプリではうまく行きます。しかしコードが数年以上前に書かれており活発にメンテされていないような場合、だんだんと難易度が増していきます。ページ内で 2 つの React のバージョンを混在させることは可能ですが、React 17 以前にこのようなことをすると不安定になり、イベント絡みの問題が引き起こされていました。

React 17 で、これらの問題の多くを修正します。これは React 18 やもっと将来のバージョンが来たときに、とれる選択肢が増えるということを意味します。選択肢のひとつは、これまでやってきたのと同様、アプリ全体を一度にアップグレードするというものです。しかし今後は、アプリを一部分ずつアップグレードするという選択肢がとれるようになります。例えば、アプリの大部分を React 18 に移行しつつ、いくつかの遅延ロードされるダイアログやサブページを React 17 のままにしておけるようになります。

だからといって段階的に更新しないといけないという訳ではありません。今後もほとんどのアプリでは、一気にアップグレードするのがベストの選択肢です。2 つのバージョンの React をロードするというのは、たとえ片方はオンデマンドで遅延ロードするのだとしても、やはり理想的ではありません。しかし、活発にメンテされていない大きなアプリではこの選択肢は検討に値するものであり、React 17 はこのようなアプリが取り残されずに済むようにします。

古いバージョンの React を必要に応じて遅延ロードするという手法をデモするためのサンプルリポジトリを用意しました。このデモは Create React App を使っていますが、他のどのようなツールでも似たアプローチが可能なはずです。他のツールを使ったデモを追加するプルリクエストを歓迎します。

補足

その他の変更は React 17 より後に延期しました。このリリースの目標は段階的なアップグレードを可能にすることです。React 17 自体へのアップグレードが難しいようでは本リリースの目的が台無しですので、そのようなことはないはずです。

イベントデリゲーションに関する変更

段階的なアップグレードを可能にするために、React のイベントシステムに幾つかの変更を加える必要がありました。React 17 がメジャーリリースとなっているのは、これらの変更が一部互換性の問題を引き起こす可能性があるからです。我々の安定性に対する取り組みについてはバージョニングについての FAQ で読むことができます。

React 17 では、React は裏で document のレベルにイベントハンドラをアタッチしないようになります。代わりに、あなたが React ツリーをレンダーしようとしているルート DOM コンテナに対してアタッチするようになります:

const rootNode = document.getElementById('root');
ReactDOM.render(<App />, rootNode);

React 16 およびそれ以前では、React はほとんどのイベントに対して document.addEventListener() のようにしていました。代わりに React 17 は、水面下で rootNode.addEventListener() という呼び出しを行うようになります。

React 17 ではイベントハンドラをドキュメントではなくルート要素にアタッチしていることを示す図

この新しい挙動により、React コードと非 React コードの統合に関して 過去 数年に わたって 報告 されて きた 様々な 問題が 解決 される ことが分かっています。

この変更により問題が出た場合は、こちらによくある解決法が載っています

その他の破壊的変更

React 17 RC のブログ記事 に React 17 におけるその他の破壊的変更について説明があります。

Facebook のプロダクトコードにおける 10 万を超えるのコンポーネントのうち、これらの変更に対応するために変更する必要があったのは 20 未満でしたので、ほとんどのアプリは React 17 にトラブルなく移行できると考えています。問題があった場合は知らせてください

新しい JSX トランスフォーム

Raect 17 は新しい JSX トランスフォームをサポートします。このサポートは React 16.14.0、React 15.7.0、React 0.14.10 にもバックポートされています。これは完全にオプトインであり、使う必要はないということに留意してください。以前の JSX トランスフォームも動作し続けますし、サポートを終了する予定はありません。

React Native

React Native のリリーススケジュールは React と異なっています。React 17 へのサポートは React Native 0.64 にて追加されました。いつものように、リリースに関する議論は React Native Community のリリースに関するイシュートラッカで追うことができます。

インストール

React 17 を npm でインストールするには以下のようにします:

npm install react@17.0.0 react-dom@17.0.0

React 17 を Yarn でインストールするには以下のようにします:

yarn add react@17.0.0 react-dom@17.0.0

CDN 経由で React の UMD ビルドも提供しています:

<script crossorigin src="https://unpkg.com/react@17.0.0/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17.0.0/umd/react-dom.production.min.js"></script>

詳細なインストール手順についてはドキュメントを参照してください。

Changelog

React

React DOM

  • Delegate events to roots instead of document. (@trueadm in #18195 and others)
  • Clean up all effects before running any next effects. (@bvaughn in #17947)
  • Run useEffect cleanup functions asynchronously. (@bvaughn in #17925)
  • Use browser focusin and focusout for onFocus and onBlur. (@trueadm in #19186)
  • Make all Capture events use the browser capture phase. (@trueadm in #19221)
  • Don’t emulate bubbling of the onScroll event. (@gaearon in #19464)
  • Throw if forwardRef or memo component returns undefined. (@gaearon in #19550)
  • Remove event pooling. (@trueadm in #18969)
  • Stop exposing internals that won’t be needed by React Native Web. (@necolas in #18483)
  • Attach all known event listeners when the root mounts. (@gaearon in #19659)
  • Disable console in the second render pass of DEV mode double render. (@sebmarkbage in #18547)
  • Deprecate the undocumented and misleading ReactTestUtils.SimulateNative API. (@gaearon in #13407)
  • Rename private field names used in the internals. (@gaearon in #18377)
  • Don’t call User Timing API in development. (@gaearon in #18417)
  • Disable console during the repeated render in Strict Mode. (@sebmarkbage in #18547)
  • In Strict Mode, double-render components without Hooks too. (@eps1lon in #18430)
  • Allow calling ReactDOM.flushSync during lifecycle methods (but warn). (@sebmarkbage in #18759)
  • Add the code property to the keyboard event objects. (@bl00mber in #18287)
  • Add the disableRemotePlayback property for video elements. (@tombrowndev in #18619)
  • Add the enterKeyHint property for input elements. (@eps1lon in #18634)
  • Warn when no value is provided to <Context.Provider>. (@charlie1404 in #19054)
  • Warn when memo or forwardRef components return undefined. (@bvaughn in #19550)
  • Improve the error message for invalid updates. (@JoviDeCroock in #18316)
  • Exclude forwardRef and memo from stack frames. (@sebmarkbage in #18559)
  • Improve the error message when switching between controlled and uncontrolled inputs. (@vcarl in #17070)
  • Keep onTouchStart, onTouchMove, and onWheel passive. (@gaearon in #19654)
  • Fix setState hanging in development inside a closed iframe. (@gaearon in #19220)
  • Fix rendering bailout for lazy components with defaultProps. (@jddxf in #18539)
  • Fix a false positive warning when dangerouslySetInnerHTML is undefined. (@eps1lon in #18676)
  • Fix Test Utils with non-standard require implementation. (@just-boris in #18632)
  • Fix onBeforeInput reporting an incorrect event.type. (@eps1lon in #19561)
  • Fix event.relatedTarget reported as undefined in Firefox. (@claytercek in #19607)
  • Fix “unspecified error” in IE11. (@hemakshis in #19664)
  • Fix rendering into a shadow root. (@Jack-Works in #15894)
  • Fix movementX/Y polyfill with capture events. (@gaearon in #19672)
  • Use delegation for onSubmit and onReset events. (@gaearon in #19333)
  • Improve memory usage. (@trueadm in #18970)

React DOM Server

  • Make useCallback behavior consistent with useMemo for the server renderer. (@alexmckenley in #18783)
  • Fix state leaking when a function component throws. (@pmaccart in #19212)

React Test Renderer

Concurrent Mode (Experimental)

Is this page useful?このページを編集する