解决似乎没有意义的 ESLint / React / Redux (Airbnb config) 错误
Resolving ESLint / React / Redux (Airbnb config) errors that don't seem to make sense
我正在研究将 ESLint(Airbnb 配置)与 React / Redux 结合使用的原则。
以下代码是标准类型的 React / Redux class,我编写它是为了享受处理 Airbnb 的所有 linting 纪律。
通过了解 Airbnb 的配置偏好,我已经解决了大部分 linting 错误,但是,有几个方面我目前不了解。它们是:
- 整个方法 renderTableHeader() 以红色标出,ESLint 告诉我:
[eslint] Expected 'this' to be used by class method
'renderTableHeader'. (class-methods-use-this) (JSX attribute)
className: string
none of the other methods have this linting problem
- 我将一个对象从 Redux 状态连接到道具(包含许多 key/objects 我需要在此 class 中迭代)。 ESLint 似乎不喜欢我将对象从状态连接到道具...给我消息:
[eslint] Prop type object
is forbidden (react/forbid-prop-types)
import PropTypes
我的状态对象是一个包含许多引用用户对象的键的对象 - 所以我需要 users
成为一个对象。这是不好的做法吗?如果是,我如何在不出现此 lint 消息的情况下连接要映射的对象?
提前致谢...这是我的 class:
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);
这两条规则解决了两个不同的问题
First: Expected 'this' to be used by class method 'renderTableHeader'. (class-methods-use-this) (JSX attribute)
className: string
如果class方法不使用this,有时可以做成静态函数。如果您确实将该方法转换为静态函数,则调用该特定方法的 class 实例也必须转换为静态调用 (MyClass.callStaticMethod())
另请注意,在上述示例中,如果将方法切换为静态方法,则调用静态方法 (let a = new A(); a.sayHi();)
的 class 实例必须更新为静态调用 (A.sayHi();)
而不是让 class 的实例调用方法
如何避免出现此警告
exceptMethods
选项允许您传递一组您希望忽略其警告的方法名称。例如,您可能有来自外部库的规范,要求您将方法作为常规函数(而不是静态方法)覆盖,并且不在函数体内使用它。在这种情况下,您可以在警告中添加要忽略的方法。
"class-methods-use-this": [<enabled>, { "exceptMethods": [<...exceptions>] }]
Second: Prop type object is forbidden (react/forbid-prop-types) import PropTypes
定义明确的 PropTypes 是一个很好的做法,例如 any
、array
、object
并没有清楚地告诉您道具的实际种类。
默认情况下,此规则会阻止使用更具体的替代项(任何、数组、对象)的模糊道具类型,但如果需要,可以禁用任何道具类型。选择默认值是因为它们有明显的替代品。 any 应该替换为 anything 。 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,
};
我正在研究将 ESLint(Airbnb 配置)与 React / Redux 结合使用的原则。
以下代码是标准类型的 React / Redux class,我编写它是为了享受处理 Airbnb 的所有 linting 纪律。
通过了解 Airbnb 的配置偏好,我已经解决了大部分 linting 错误,但是,有几个方面我目前不了解。它们是:
- 整个方法 renderTableHeader() 以红色标出,ESLint 告诉我:
[eslint] Expected 'this' to be used by class method 'renderTableHeader'. (class-methods-use-this) (JSX attribute) className: string
none of the other methods have this linting problem
- 我将一个对象从 Redux 状态连接到道具(包含许多 key/objects 我需要在此 class 中迭代)。 ESLint 似乎不喜欢我将对象从状态连接到道具...给我消息:
[eslint] Prop type
object
is forbidden (react/forbid-prop-types) import PropTypes
我的状态对象是一个包含许多引用用户对象的键的对象 - 所以我需要 users
成为一个对象。这是不好的做法吗?如果是,我如何在不出现此 lint 消息的情况下连接要映射的对象?
提前致谢...这是我的 class:
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);
这两条规则解决了两个不同的问题
First: Expected 'this' to be used by class method 'renderTableHeader'. (class-methods-use-this) (JSX attribute) className: string
如果class方法不使用this,有时可以做成静态函数。如果您确实将该方法转换为静态函数,则调用该特定方法的 class 实例也必须转换为静态调用 (MyClass.callStaticMethod())
另请注意,在上述示例中,如果将方法切换为静态方法,则调用静态方法 (let a = new A(); a.sayHi();)
的 class 实例必须更新为静态调用 (A.sayHi();)
而不是让 class 的实例调用方法
如何避免出现此警告
exceptMethods
选项允许您传递一组您希望忽略其警告的方法名称。例如,您可能有来自外部库的规范,要求您将方法作为常规函数(而不是静态方法)覆盖,并且不在函数体内使用它。在这种情况下,您可以在警告中添加要忽略的方法。
"class-methods-use-this": [<enabled>, { "exceptMethods": [<...exceptions>] }]
Second: Prop type object is forbidden (react/forbid-prop-types) import PropTypes
定义明确的 PropTypes 是一个很好的做法,例如 any
、array
、object
并没有清楚地告诉您道具的实际种类。
默认情况下,此规则会阻止使用更具体的替代项(任何、数组、对象)的模糊道具类型,但如果需要,可以禁用任何道具类型。选择默认值是因为它们有明显的替代品。 any 应该替换为 anything 。 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,
};