web-dev-qa-db-ja.com

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

私はReactでReduxを学んでいて、このコードにつまずいた。それが Redux 特有であるかどうかはわかりませんが、例の1つで次のコードスニペットを見ました。

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

connectの機能は非常に簡単ですが、connectより前の@は理解できません。私が間違っていなければ、JavaScriptの演算子でさえありません。

誰がこれを説明してください、そしてなぜそれが使われているのですか?

更新:

実際にはReactコンポーネントをReduxストアに接続するために使われる react-redux の一部です。

208
Salman

@シンボルは、実際には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 を使って利用できます。

354
Tanner Semerad

非常に重要です!

これらのプロップは状態プロップと呼ばれ、通常のプロップとは異なります。コンポーネントの状態プロップを変更すると、これらのプロップを使用しなくてもコンポーネントのレンダリングメソッドが繰り返しトリガーされますパフォーマンス上の理由は、コンポーネント内に必要な状態プロップのみをコンポーネントにバインドし、サブプロップを使用する場合はこれらのプロップのみをバインドするようにします。

例:あなたのコンポーネントの中に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]
}))
42