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
大声笑,我现在正在深入研究redux和其他内容。但是那时候我还不知道装饰语法与redux无关。它只是JavaScript。很高兴看到这个问题正在帮助很多像我这样的人。:)
Salman

1
显然,redux团队目前不鼓励使用connect作为装饰器github.com/happypoulp/redux-tutorial/issues/87
Syed Jafri

Answers:


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

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

很重要!

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

例如:假设您的组件内部仅需要两个道具:

  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
或使用重新选择或快速记忆之类的选择器
Julius Koronci

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.