【问题标题】:What's the '@' (at symbol) in the Redux @connect decorator?Redux @connect 装饰器中的“@”(at 符号)是什么?
【发布时间】:2016-10-12 02:28:11
【问题描述】:

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

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

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

谁能解释一下这是什么以及为什么使用它?

更新:

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

【问题讨论】:

  • 我对 Redux 不熟悉,但它看起来像一个装饰器。 medium.com/google-developers/…
  • 我喜欢在这个新的 JavaScript 世界中,你有一半时间盯着代码并思考“这是语言语法的哪一部分?”
  • 大声笑,我现在已经深入研究 redux 和其他东西了。但是当时我并不知道装饰器语法与redux无关。它只是 JavaScript。很高兴看到这个问题帮助了很多像我这样的人。 :)
  • 显然 redux 团队目前不鼓励使用 connect 作为装饰器 github.com/happypoulp/redux-tutorial/issues/87

标签: javascript reactjs decorator redux


【解决方案1】:

非常重要!

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

示例: 假设在您的组件内部,您只需要两个道具:

  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]
}))

【讨论】:

【解决方案2】:

@ 符号实际上是一个 JavaScript 表达式 currently proposed to signify decorators

装饰器可以在设计时注释和修改类和属性。

下面是一个不带装饰器和带装饰器设置 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

【讨论】:

  • 使用 ES6 语法甚至可以更简洁。 @connect( state => { return { todos: state.todos }; }, dispatch => { return {actions: bindActionCreators(actionCreators, dispatch)}; })
  • 如果你真的想要简洁,你可以在 ES6 中使用隐式返回。这取决于你想变得多么明确。 @connect(state => ({todos: state.todos}), dispatch => ({actions: bindActionCreators(actionCreators, dispatch)}))
  • 如何导出未连接的组件进行单元测试?
  • 使用带有 react-navigation 的 redux 装饰器可能会出现问题,目前的最佳实践是使用函数而不是装饰器:github.com/react-community/react-navigation/issues/1180
  • 例子真的很有帮助
猜你喜欢
  • 1970-01-01
  • 2019-03-07
  • 1970-01-01
  • 2016-11-25
  • 2011-02-25
  • 1970-01-01
  • 1970-01-01
  • 2017-04-02
相关资源
最近更新 更多