React 15.5へのアップデート手順(prop-typesとReact.createClass)

  • 68
    Like
  • 2
    Comment

React 15.5がリリースされ、今までは同梱されていたReact.PropTypesReact.createClassが非推奨となりそれぞれ別パッケージに分かれました。

React.PropTypesprop-typesへマイグレーションする方法としてcodemodのスクリプトが提供されています。

React 15.5の警告内容

単純にReact 15.5へアップデートするとReact.PropTypesReact.createClassのコンソールエラーが表示されます。
まだ非推奨の警告だけなので16.0のメジャーアップデートまでは普通に動作します。

Warning: React.createClass is deprecated and will be removed in version 16. Use plain JavaScript classes instead. If you're not yet ready to migrate, create-react-class is available on npm as a drop-in replacement.

Warning: Accessing PropTypes via the main React package is deprecated. Use the prop-types package from npm instead.

などの警告がでます。

shopping cart example 2017-04-09 15-28-00.png

マイグレーション手順

React.PropTypes

  1. jscodeshiftをインストール
  2. react-codemodのマイグレーションスクリプトをローカルにコピー
  3. jscodeshift + react-codemodでファイルを変換
  4. prop-typesをnpm install
npm install -g jscodeshift
git clone https://github.com/reactjs/react-codemod.git
# React-PropTypes-to-prop-types.jsのパスをコピーする
# echo `pwd`/react-codemod/transforms/React-PropTypes-to-prop-types.js | pbcopy
# 指定したファイルのPropTypesをjscodeshiftで変換
find src/components -name "*.js" | xargs jscodeshift -t "React-PropTypes-to-prop-types.jsへのパス"


Processing 6 files...
Spawning 3 workers...
Sending 2 files to free worker...
Sending 2 files to free worker...
Sending 2 files to free worker...
All done.
Results:
0 errors
0 unmodified
2 skipped
4 ok
Time elapsed: 3.580seconds

個別にJavaScriptファイルを指定する場合は、次のような感じ。

jscodeshift -t "React-PropTypes-to-prop-types.jsへのパス" "変更したいJavaScriptファイルのパス"

これで自動的に React.PropTypesprop-types へ変換してくれます。

後は忘れずにReact 15.5へのアップデートとprop-typesをインストールすれば完了です。

npm i -S react@^15.5 react-dom@^15.5 prop-types

:warning: 変換に失敗する

TypeError: Cannot read property 'name' of undefined

というエラーがでて変換に失敗する問題は、次のPRで解決されそうです。

React.createClass

React.createClassの場合もスクリプトが違うだけ基本的には同じです。
react-codemodのclass.jsを使い、React.createClassReact.Componentへ変換します。

$ find src/components -name "*.js" | xargs jscodeshift -t /Users/azu/.ghq/github.com/react/react-codemod/transforms/class.js
Processing 6 files...
Spawning 3 workers...
Sending 2 files to free worker...
Sending 2 files to free worker...
Sending 2 files to free worker...
All done.
Results:
0 errors
1 unmodified
0 skipped
5 ok
Time elapsed: 4.826seconds

React.createClassの方はオプションもあるので、READMEを読むと良いと思います。

注意点としては、上記のスクリプトはまだProposal段階のtc39/proposal-class-public-fieldsを前提に変換してきます。

そのため、次のようにES2017段階ではパースできないコードが生成されます。
(React.createClassはauto bindしているため、method = () => {}でそれを実現するためだと思います)

    static propTypes = {
        products: PropTypes.arrayOf(PropTypes.shape({
            id: PropTypes.number.isRequired,
            title: PropTypes.string.isRequired,
            price: PropTypes.number.isRequired,
            quantity: PropTypes.number.isRequired
        })).isRequired,
        total: PropTypes.string.isRequired,
        onCheckoutClicked: PropTypes.func.isRequired
    };

これをgetterなどに直すか、BabelのClass properties transformなど使って変換する必要があります。

自分は、babel-preset-stage-2を入れて解決させました。(+ .babelrcへ追加)

npm i -D babel-preset-stage-2

その他

codemodにはdouble quoteとかのオプションもありますが、ESLintの--fixで後からスタイルを揃えました。

変換結果

Alminalmin/exampleをまとめてReact 15.5へアップデートした結果を次のPRで見ることができます。

9.9割ぐらいはコマンドラインのみでアップデートが完結しました。

Stateless functionがあるファイルの変換が上手くできなかったので手動で変更しました。