【问题标题】:Resolving ESLint / React / Redux (Airbnb config) errors that don't seem to make sense解决似乎没有意义的 ESLint / React / Redux (Airbnb config) 错误
【发布时间】:2018-07-25 07:57:34
【问题描述】:

我正在学习将 ESLint(Airbnb 配置)与 React / Redux 结合使用。

以下代码是一个标准类型的 React / Redux 类,我编写它是为了享受处理 Airbnb 的所有 linting 规则。

通过了解 Airbnb 的配置偏好,我解决了大部分 linting 错误,但是,我目前不了解一些领域。它们是:

  1. 整个方法 renderTableHeader() 用红色标出,ESLint 告诉我:

[eslint] 期望 'this' 被类方法使用 'renderTableHeader'。 (class-methods-use-this) (JSX 属性) 类名:字符串

其他方法都没有这种掉毛问题

  1. 我将一个对象从 Redux 状态连接到 props(包含许多我需要在此类中迭代的键/对象)。 ESLint 似乎不喜欢我将对象从状态连接到道具......给我的信息:

[eslint] Prop 类型 object 被禁止 (react/forbid-prop-types) 导入道具类型

我的状态对象是一个包含许多引用用户对象的键的对象 - 所以我需要 users 成为一个对象。这是不好的做法吗?如果是这样,我将如何在不出现此 lint 消息的情况下连接对象进行映射?

提前谢谢...这是我的课程:

import React, { Component } from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import _ from 'lodash';
import { getUsers } from '../actions/getUsers';
import setUserMarketingPref from '../actions/setUserMarketingPref';
import { setFilter } from '../actions/setFilter';
import TableRow from '../components/TableRow';
import '../styles/styles.css';

class AppContainer extends Component {
  componentDidMount() {
    this.props.getUsers();
  }

  renderTableHeader() {
    return (
      <div className="table__header">
        <div className="table__header--name">Name</div>
        <div className="table__header--gender">Gender</div>
        <div className="table__header--region">Region</div>
      </div>
    );
  }

  renderTable() {
    const { users, filterMode } = this.props;
    const usersView = filterMode ? _.omitBy(users, user => !user.checked) : users;
    return _.map(usersView, user => (
      <TableRow
        user={user}
        key={user.id}
        setUserMarketingPref={_.debounce(() => this.props.setUserMarketingPref(user.id), 100)}
      />
    ));
  }

  renderFilters() {
    return (
      <div className="table__buttons">
        <button
          id="marketing-other"
          className="table__other"
          onClick={e => this.props.setFilter(e.target.id)}
        >Other filter
        </button>
        <button
          id="marketing-none"
          className="table__no-marketing"
          onClick={e => this.props.setFilter(e.target.id)}
        >No marketing
        </button>
      </div>
    );
  }

  render() {
    if (!_.size(this.props.users)) {
      return null;
    }
    return (
      <div className="table__container">
        {this.renderTableHeader()}
        {this.renderTable()}
        {this.renderFilters()}
      </div>
    );
  }
}

const mapDispatchToProps = dispatch => bindActionCreators(
  {
    getUsers,
    setUserMarketingPref,
    setFilter,
  },
  dispatch,
);

const mapStateToProps = state => ({
  users: state.users,
  filter: state.filter,
  filterMode: state.marketing.filterMode,
});

AppContainer.defaultProps = {
  filterMode: false,
  getUsers: null,
  setUserMarketingPref: null,
  setFilter: null,
};

AppContainer.propTypes = {
  users: PropTypes.object,
  filterMode: PropTypes.bool,
  getUsers: PropTypes.func,
  setUserMarketingPref: PropTypes.func,
  setFilter: PropTypes.func,
};

export default connect(mapStateToProps, mapDispatchToProps)(AppContainer);

【问题讨论】:

  • 看起来 eslint 只是在抱怨列表中的第一个函数。使用this 可能会导致它抱怨renderTable()。我认为他们想要定义对象的形状,或者您可以禁用该线。由你决定。 reactjs.org/docs/typechecking-with-proptypes.html

标签: reactjs redux react-redux eslint eslint-config-airbnb


【解决方案1】:

这两条规则解决了两个不同的问题

首先: 类方法“renderTableHeader”应使用“this”。 (class-methods-use-this) (JSX 属性) 类名:字符串

根据documentation

如果类方法不使用this,有时可以做成静态函数。如果您确实将方法转换为静态函数,则调用该特定方法的类的实例也必须转换为静态调用(MyClass.callStaticMethod())

在上面的例子中还要注意,如果你将一个方法切换到一个静态方法,调用静态方法(let a = new A(); a.sayHi();)的类的实例必须更新为静态调用(A.sayHi();),而不是拥有类调用方法

如何避免出现此警告

exceptMethods 选项允许您传递您希望忽略警告的方法名称数组。例如,您可能有来自外部库的规范,要求您将方法覆盖为常规函数(而不是静态方法),并且不在函数体内使用 this。在这种情况下,您可以在警告中添加要忽略的方法。

"class-methods-use-this": [<enabled>, { "exceptMethods": [<...exceptions>] }]

第二个: Prop类型对象被禁止(react/forbid-prop-types)导入PropTypes

定义不模糊的 PropType 是一个很好的做法,例如 any、array、object,它们并不能清楚地告诉你 prop 实际上是什么类型。

根据documentation

默认情况下,此规则通过更具体的替代方案(任何、数组、对象)来防止模糊的道具类型,但如果需要,可以禁用任何道具类型。选择默认值是因为它们有明显的替换。 any 应该替换为,好吧,任何东西。 array 和 object 可以分别替换为 arrayOf 和 shape。

在你的情况下,user 是一个类似的对象

{
    id: 123,
    name: 'abc'
}

你可以像这样定义 PropType

AppContainer.propTypes = {
  users: PropTypes.shape({
    id: PropTypes.number,
    name: PropTypes.string
  }),,
  filterMode: PropTypes.bool,
  getUsers: PropTypes.func,
  setUserMarketingPref: PropTypes.func,
  setFilter: PropTypes.func,
};

【讨论】:

  • ...感谢@Shubham Khatri。一个非常有据可查的答案。你知道将静态方法放入组件有什么好处吗?即它是纯粹的风格还是有任何好处,即性能等
  • 完美解释!!感谢您的帮助!
猜你喜欢
  • 2018-04-21
  • 2017-01-22
  • 2017-10-04
  • 2018-02-02
  • 2016-07-24
  • 2016-07-02
  • 2019-05-05
  • 2018-12-25
  • 1970-01-01
相关资源
最近更新 更多