Redux @connectデコレーターの '@'(アットマーク)は何ですか?


226

私はReactでReduxを学んでいて、このコードに出くわしました。Redux固有かどうかはわかりませんが、いずれかの例で次のコードスニペットを確認しました。

@connect((state) => {
  return {
    key: state.a.b
  };
})

の機能connectはかなり単純ですが、@以前はわかりませんconnect。私が間違っていなければ、それはJavaScriptオペレーターでさえありません。

誰かがこれは何で、なぜそれが使用されているのか説明してもらえますか?

更新:

実際react-reduxには、ReactコンポーネントをReduxストアに接続するために使用されます。


6
Reduxについてはよく知りませんが、デコレータのように見えます。medium.com/google-developers/...
リー・

4
この新しいJavaScriptの世界で、コードの半分をじっと見つめ、「これは言語構文のどの部分なのか?」
MK。

4
Lol、私はreduxやその他のことについて深く理解しています。しかし、当時、私はデコレータの構文がreduxとは何の関係もないことを知りませんでした。その単なるJavaScript。この質問を見てうれしいですが、私のような多くの人々を助けています。:)
Salman

1
どうやらreduxチームは現時点でデコレータとしての接続の使用を推奨していませんgithub.com/happypoulp/redux-tutorial/issues/87
Syed Jafri 2017

回答:


376

@記号は、実際にはJavaScript式で、現在意味するために提案されているデコレータ

デコレータを使用すると、設計時にクラスやプロパティに注釈を付けたり変更したりできます。

デコレータを使用しない場合と使用する場合のReduxの設定例を以下に示します。

デコレーターなし

import React from 'react';
import * as actionCreators from './actionCreators';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';

function mapStateToProps(state) {
  return { todos: state.todos };
}

function mapDispatchToProps(dispatch) {
  return { actions: bindActionCreators(actionCreators, dispatch) };
}

class MyApp extends React.Component {
  // ...define your main app here
}

export default connect(mapStateToProps, mapDispatchToProps)(MyApp);

デコレーターの使用

import React from 'react';
import * as actionCreators from './actionCreators';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';

function mapStateToProps(state) {
  return { todos: state.todos };
}

function mapDispatchToProps(dispatch) {
  return { actions: bindActionCreators(actionCreators, dispatch) };
}

@connect(mapStateToProps, mapDispatchToProps)
export default class MyApp extends React.Component {
  // ...define your main app here
}

上記の例はどちらも同等ですが、それは好みの問題です。また、デコレータ構文はまだJavaScriptランタイムに組み込まれておらず、まだ実験段階であり、変更される可能性があります。利用したい場合はBabelで利用できます。


46
これはすごい
svnm 2015年

2
ES6構文を使用すると、さらに簡潔にすることができます。@connect(state => {return {todos:state.todos};}、dispatch => {return {actions:bindActionCreators(actionCreators、dispatch)};})
LessQuesar

11
本当に簡潔になりたい場合は、ES6で暗黙のリターンを使用できます。それはあなたがどのくらい明確になりたいかに依存します。@connect(state => ({todos: state.todos}), dispatch => ({actions: bindActionCreators(actionCreators, dispatch)}))
Tanner Semerad

3
単体テストのために未接続のコンポーネントをどのようにエクスポートしますか?
tim

:反応-ナビゲーションが問題となる可能性があるとのReduxのためにデコレータを使用すると、現在のベストプラクティスではありませんデコレータ機能を使用することですgithub.com/react-community/react-navigation/issues/1180
straya

50

非常に重要です!

これらの小道具は状態小道具と呼ばれ、通常の小道具とは異なります。コンポーネントの小道具を変更すると、これらの小道具を使用しない場合でもコンポーネントのレンダリングメソッドが何度もトリガーされるため、パフォーマンス上の理由からコンポーネントのみにバインドしようとしますコンポーネント内で必要な状態の小道具、およびサブ小道具を使用する場合は、これらの小道具のみをバインドします。

例:コンポーネント内で必要なプロップは2つだけです:

  1. 最後のメッセージ
  2. ユーザー名

これをしないでください

@connect(state => ({ 
   user: state.user,
   messages: state.messages
}))

これを行う

@connect(state => ({ 
   user_name: state.user.name,
   last_message: state.messages[state.messages.length-1]
}))

9
または、reselectやfastmemoizeなどのセレクターを使用する
Julius Koronci 2017年

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.