I'm working through the discipline of using ESLint (Airbnb config) with React / Redux.
The following code is a standard type React / Redux class that I've written to enjoy dealing with all of Airbnb's linting discipline.
Most of the linting errors I've resolved by understanding what Airbnb's configuration prefers, however, there are a couple of areas that I presently don't understand. These are:
[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
[eslint] Prop type
object
is forbidden (react/forbid-prop-types) import PropTypes
My state object is an object containing many keys that reference user objects - so I need users
to be an object. Is this bad practice? If it is how would I connect an object to map over without this lint message appearing?
Thanks in advance...here's my 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);
The two rules address two different things
First: Expected 'this' to be used by class method 'renderTableHeader'. (class-methods-use-this) (JSX attribute) className: string
According to the documentation
If a class method does not use this, it can sometimes be made into a static function. If you do convert the method into a static function, instances of the class that call that particular method have to be converted to a static call as well (MyClass.callStaticMethod())
Also note in the above examples that if you switch a method to a static method, instances of the class that call the static method (let a = new A(); a.sayHi();)
have to be updated to being a static call (A.sayHi();)
instead of having the instance of the class call the method
How to avoid having this warning
The exceptMethods
option allows you to pass an array of method names for which you would like to ignore warnings. For example, you might have a spec from an external library that requires you to overwrite a method as a regular function (and not as a static method) and does not use this inside the function body. In this case, you can add that method to ignore in the warnings.
"class-methods-use-this": [<enabled>, { "exceptMethods": [<...exceptions>] }]
Second: Prop type object is forbidden (react/forbid-prop-types) import PropTypes
It is a good practise to define PropTypes that are not vague, example any
, array
, object
which do not clearly tell you what kind the prop actually is.
According to the documentation
By default this rule prevents vague prop types with more specific alternatives available (any, array, object), but any prop type can be disabled if desired. The defaults are chosen because they have obvious replacements. any should be replaced with, well, anything. array and object can be replaced with arrayOf and shape, respectively.
In your case say is user
is an object like
{
id: 123,
name: 'abc'
}
you could define the PropType like
AppContainer.propTypes = {
users: PropTypes.shape({
id: PropTypes.number,
name: PropTypes.string
}),,
filterMode: PropTypes.bool,
getUsers: PropTypes.func,
setUserMarketingPref: PropTypes.func,
setFilter: PropTypes.func,
};
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.