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

IT技术 javascript reactjs decorator redux
2021-02-19 15:46:37

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

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

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

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

更新:

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

2个回答

@符号实际上是目前提议用于表示装饰器的 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

使用带有反应导航的 redux 装饰器可能会出现问题,当前的最佳实践是使用该函数而不是装饰器:github.com/react-community/react-navigation/issues/1180
2021-04-24 15:46:37
如果你真的想要简洁,你可以在 ES6 中使用隐式返回。这取决于你想表现得有多明确。@connect(state => ({todos: state.todos}), dispatch => ({actions: bindActionCreators(actionCreators, dispatch)}))
2021-05-02 15:46:37
这些例子真的很有帮助
2021-05-05 15:46:37
使用 ES6 语法甚至可以更简洁。@connect( state => { return { todos: state.todos }; }, dispatch => { return {actions: bindActionCreators(actionCreators, dispatch)}; } )
2021-05-12 15:46:37
您将如何导出未连接的组件以进行单元测试?
2021-05-17 15:46:37

很重要!

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

示例:让我们说在你的组件中你只需要两个props:

  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]
}))
或使用选择器,如 reselect 或 fastmemoize
2021-05-13 15:46:37