Babel6を使ってreact-redux(バージョンは4.0.6)の@connectを気軽に使おうとしたらサクッとハマりました。
以下の事項に関して気をつける必要があります。
1.babel-plugin-transform-decoratorsを使わない
babel-plugin-transform-decoratorsはBabel6になったタイミングで仕様?が変わったため、そのまま利用すると正しく動作しません。以下のようなエラーが出ます。
Decorators are not supported yet in 6.x pending proposal update.
エラーにさせずに期待通りの動きをさせるためには、babel-plugin-transform-decorators-legacyを使う必要があります。Babel5とBabel6でdecoratorの動きがどのように変わったかはまだ検証しきれてないのでここでは触れません。
.babelrc
(あるいはpackage.json
のbabelプロパティ)には、忘れずにtransform-decorators-legacy
を追加しておきましょう。
"babel": {
"presets": [
"es2015"
],
"plugins": [
"transform-decorators-legacy"
]
},
※ この辺りも見るにpresetsにstage-0
(むしろstage-1
)を設定する必要があるのかなと思いましたがなくても大丈夫でした。あとで確認しよう...。
2.staticプロパティ定義をES7記法に合わせる
reduxの#589でも言及されていますが、ES7のDecoratorとClassPropertiesをES6で代替する記法は両立しません。
こんなエラーになります。
Uncaught Invariant Violation: Could not find "store" in either the context or props of "Connect(XXXX)". Either wrap the root component in a , or explicitly pass "store" as a prop to "Connect(XXXX)".
具体的には、こういう記述はNGになります。
@connect
class Stuff {}
Stuff.contextTypes = {
router: React.PropTypes.object,
};
これを回避するためには以下のようにES7で書く必要があります。
@connect
class Stuff {
static contextTypes = {
router: React.PropTypes.object
}
}
ClassPropertiesを使うので、babel-plugin-transform-class-propertiesのインストールと、babelのplugin設定をお忘れなく。
"babel": {
"presets": [
"es2015"
],
"plugins": [
"transform-decorators-legacy",
"transform-class-properties",
]
}
TODO
- Babel5とBabel6でのDecoratorの仕様や挙動の違いを検証する。
- Babelのpresetsについて再度確認する。
以上です。