Что означает "@" (символ) в декораторе Redux @connect?

Я изучаю Redux с React и наткнулся на этот код. Я не уверен, что это Redux конкретный или нет, но я видел следующий фрагмент кода в одном из примеров.

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

Хотя функциональность connect довольно проста, но я не понимаю @ до connect. Это даже не оператор JavaScript, если я не ошибаюсь.

Может кто-нибудь объяснить, пожалуйста, что это такое и почему он используется?

Обновление:

На самом деле это часть react-redux, которая используется для подключения компонента React к хранилищу Redux.

Ответ 1

Символ @ на самом деле является выражением 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.

Ответ 2

Очень важно!

Эти реквизиты называются государственными реквизитами, и они отличаются от обычных реквизитов, любые изменения в реквизитах состояния компонента будут вызывать метод рендеринга компонентов снова и снова, даже если вы не используете эти реквизиты для Причины эффективности попытайтесь привязать к вашему компоненту только реквизиты состояния, которые вам нужны внутри вашего компонента, и если вы используете вспомогательные реквизиты, свяжите их только с реквизитами.

Пример: скажем, внутри вашего компонента вам нужны только два реквизита:

  • последнее сообщение
  • имя пользователя

не делайте этого

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

сделать это

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