Устранение ошибок ESLint / React / Redux (конфигурация Airbnb), которые не имеют смысла

Я работаю через дисциплину использования ESLint (Airbnb config) с React / Redux.

Следующий код является классом React / Redux стандартного типа, который я написал для того, чтобы получать удовольствие от работы со всеми дисциплинами в Airbnb.

Большинство ошибок обработки я исправил, поняв, что предпочитает конфигурация Airbnb, однако есть несколько областей, которые я в настоящее время не понимаю. Это:

  1. Весь метод renderTableHeader() выделен красным, а ESLint сообщает мне:

[eslint] Ожидается, что this будет использоваться методом класса renderTableHeader. (class-method-use-this) (атрибут JSX) className: строка введите описание изображения здесь

ни один из других методов не имеет этой проблемы с ворсом

  1. Я подключаю объект из состояния Redux к реквизиту (содержит много ключей / объектов, которые мне нужно перебрать в этом классе). ESLint, похоже, не любит, когда я проводя объекты из состояния в реквизит... давая мне сообщение:

[eslint] Тип опоры object Запрещен (реагировать / запрещать-проп-типы) импорт PropTypes

введите описание изображения здесь

Мой объект состояния - это объект, содержащий много ключей, которые ссылаются на объекты пользователя - поэтому мне нужно users быть объектом. Это плохая практика? Если это так, как я могу подключить объект к карте без появления этого сообщения?

Заранее спасибо... вот мой класс:

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);

1 ответ

Решение

Два правила касаются двух разных вещей

Первое: ожидалось, что this будет использоваться методом класса renderTableHeader. (class-method-use-this) (атрибут JSX) className: строка

Согласно документации

Если метод класса не использует это, его иногда можно превратить в статическую функцию. Если вы преобразуете метод в статическую функцию, экземпляры класса, которые вызывают этот конкретный метод, также должны быть преобразованы в статический вызов. (MyClass.callStaticMethod())

Также обратите внимание на приведенные выше примеры, что если вы переключаете метод на статический метод, экземпляры класса, которые вызывают статический метод (let a = new A(); a.sayHi();) должны быть обновлены, чтобы быть статическим вызовом (A.sayHi();) вместо того, чтобы экземпляр класса вызывал метод

Как избежать этого предупреждения

exceptMethods Опция позволяет передавать массив имен методов, для которых вы хотели бы игнорировать предупреждения. Например, у вас может быть спецификация из внешней библиотеки, которая требует, чтобы вы перезаписывали метод как обычную функцию (а не как статический метод) и не использовали ее внутри тела функции. В этом случае вы можете добавить этот метод, чтобы игнорировать в предупреждениях.

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

Второе: объект типа Prop запрещен (реакции / запрещать-проп-типы).

Хорошей практикой является определение пропутанных типов, например: 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,
};
Другие вопросы по тегам