Redux @connect装饰器中的'@'(符号)是什么?

Sal*_*man 216 javascript decorator reactjs redux

我正在使用React学习Redux并且偶然发现了这段代码.我不确定它是否特定于Redux,但我在其中一个示例中看到了以下代码片段.

@connect((state) => {
  return {
    key: state.a.b
  };
})
Run Code Online (Sandbox Code Playgroud)

虽然功能connect非常简单,但我@之前并不理解connect.如果我没错,它甚至不是JavaScript运算符.

有人可以解释一下这是什么,为什么用它?

更新:

事实上,react-redux它的一部分用于将React组件连接到Redux存储.

Tan*_*rad 365

@符号实际上是一个当前提出用于表示装饰器的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);
Run Code Online (Sandbox Code Playgroud)

使用装饰器

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
}
Run Code Online (Sandbox Code Playgroud)

以上两个例子都是等价的,只是一个偏好问题.此外,装饰器语法尚未构建到任何Javascript运行时中,并且仍然是实验性的并且可能会发生变化.如果您想使用它,可以使用Babel.

  • 这太棒了 (43认同)
  • 如果你真的想要简洁,你可以在ES6中使用隐式返回.这取决于你想要多么明确.`@connect(state =>({todos:state.todos}),dispatch =>({actions:bindActionCreators(actionCreators,dispatch)})) (11认同)
  • 很好的答案,喜欢代码示例的比较! (6认同)
  • 如何导出未连接的组件进行单元测试? (3认同)
  • 使用ES6语法甚至可以更简洁.@connect(state => {return {todos:state.todos};},dispatch => {return {actions:bindActionCreators(actionCreators,dispatch)};}) (2认同)

Far*_*uti 45

很重要!

这些道具被称为状态道具,它们与普通道具不同,对组件状态道具的任何更改都会一次又一次地触发组件渲染方法,即使您不使用这些道具也是如此,因为性能原因尝试仅绑定到您的组件在组件内部需要的状态道具,如果使用子道具,则只绑定这些道具.

例如:让我们说你的组件内只需要两个道具:

  1. 最后一条消息
  2. 用户名

不要这样做

@connect(state => ({ 
   user: state.user,
   messages: state.messages
}))
Run Code Online (Sandbox Code Playgroud)

做这个

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

  • 或使用选择器,如重新选择或fastmemoize (9认同)