This code:
class MyComponent extends Component {
state = {
foo: true, <---- here eslint shows error
bar: [1, 2, 3],
}
fooBar = () => {
this.setState(prevState => ({
bar: prevState.foo ? prevState.bar.sort() : prevState.bar.reverse(),
foo: !prevState.foo,
}))
}
render() {
return (<div onClick={this.fooBar}>{...this.state.bar}</div>)
}
}
But eslint shows error for foo, no-unused-state is displayed, but it is being used.
Can you share the error, and your eslint config?
Same here.
onTitleChange = (title) => {
this.setState({ title, titleChanged: true });
}
onTemplateChange = (template) => {
this.props.navigator.pop();
this.setState((state => ({
template,
title: state.titleChanged ? state.title : getTemplateTitle(template),
})));
};
97:28 error Unused state field: 'titleChanged' react/no-unused-state
I'm using eslint-config-airbnb
Your eslint config must be different, because the airbnb config does not permit class properties to be used.
I'm also using eslint-config-airbnb and get the same error
@cristianfraser same question; can you share your code and your eslint config?
Again, if you're using class properties, you're violating the airbnb style guide, so if you are, you must be using a modified eslint config.
{
"parser": "babel-eslint",
"extends": [
"airbnb"
],
"env": {
"mocha": true
},
"rules": {
"no-restricted-properties": "off",
"complexity": [ "error", 10 ],
"max-depth": [ "error", 4 ],
"max-nested-callbacks": [ "error", 2 ],
"max-params": [ "error", 4 ],
"max-statements": [ "error", 18 ],
"no-constant-condition": "off",
"no-plusplus": "off",
"no-warning-comments": "error",
"comma-dangle": [
"error",
{
"arrays": "always-multiline",
"objects": "always-multiline",
"imports": "always-multiline",
"exports": "always-multiline",
"functions": "always-multiline"
}
],
"no-restricted-globals": "off",
"react/require-default-props": "off",
"react/no-unused-prop-types": "off",
"react/jsx-filename-extension": [
"warn",
{
"extensions": [".js"]
}
],
"react/jsx-no-bind": [
"error",
{
"ignoreRefs": false,
"allowArrowFunctions": false,
"allowBind": false
}
],
"react/no-typos": "off",
"import/no-named-as-default": "off",
"import/prefer-default-export": "off",
"jsx-a11y/href-no-hash": "off",
"jsx-a11y/anchor-is-valid": "off",
"react-native/split-platform-components": "off",
"react-native/no-unused-styles": "error",
"react-native/no-inline-styles": "error",
"react-native/no-color-literals": "error"
},
"globals": {
"__DEV__": true,
"fetch": true,
"ErrorUtils": true
},
"plugins": [
"react-native"
]
}
This is a minimal code that shows no-unused-state for ascending:
import React from 'react'
export default class TestComponent extends React.Component {
state = {
list: [1, 2, 3],
ascending: true,
}
onClick = () => {
this.setState(({ list, ascending }) => {
if (ascending) {
return {
list: list.sort(),
ascending: !ascending,
}
}
return {
list: list.reverse(),
ascending: !ascending,
}
})
}
render() {
return (
<div>
<button onClick={this.onClick}>Click me</button>
{this.state.list.map(item => <div>{item}</div>)}
</div>
)
}
}
This is my eslint config:
{
"extends": "airbnb",
"parser": "babel-eslint",
"env": {
"browser": true,
"node": true,
"es6": true,
"jest": true
},
"plugins": [
"react"
],
"settings": {
"import/resolver": {
"webpack": { "config": "webpack/dev.config.js" }
}
},
"rules": {
"camelcase": 0,
"semi": [2, "never"],
"react/require-default-props": 0,
"react/jsx-filename-extension": 0,
"jsx-a11y/label-has-for": [2, {
"components": ["label"],
"required": { "some": ["nesting", "id"] }
}],
"jsx-a11y/click-events-have-key-events": 0,
"jsx-a11y/anchor-is-valid": ["error", {
"components": ["Link"],
"specialLink": ["to"],
"aspects": ["noHref", "invalidHref", "preferButton"]
}],
}
}
Also, I've used class properties with plain config-airbnb with no problems.
@cristianfraser you can only use it with babel-eslint; the airbnb config uses the default parser. It's likely the react-native plugin is enabling that as well, of course.
What do you mean by I can only use it with babel-eslint? That's what's in my config, that's the wrong parser for that rule? Is what's happening the expected behaviour in this case?
@cristianfraser eslint core doesn't support parsing class properties; only babel-eslint does - thus if you just had extends: "airbnb" you wouldn't be able to use them.
What's happening seems like a bug in the no-unused-state rule, I'm just trying to gather as much info about it as possible :-)
cc @wbinnssmith @jackyho112
@ljharb Thanks for tagging me! This rule doesn't support arrow function definition as class method currently. I think this will add it.
Fixed with #1411
I'm having a same problem with latest verstion.
state = {
removeQueue: [], <--- unused state field: 'removeQueue'
}
onUpdate = (date, id) => {
this.setState(prevState => ({
removeQueue: [...prevState.removeQueue, { date, id }],
}));
}
I'm using removeQueue in functional setState, but eslint shows error.
Try making onUpdate a constructor-bound instance method (putting arrow functions in class properties is a bad practice) and it should pick it up.
constructor() {
super();
this.onUpdate = this.onUpdate.bind(this);
}
onUpdate(date, id) {
this.setState(prevState => ({
removeQueue: [...prevState.removeQueue, { date, id }],
}));
}
I've changed it like this.
But it shows me the same error...
Thanks - could you file a new issue with both code examples (the class field and the instance method)?
sure!
I meet the same error. Here is my minimal code:
~~~jsx
import React from 'react';
class Test extends React.Component {
static Sub({ state }) {
const { property } = state;
return
{property}
;state = {
property: 1 // Unused state field 'property'
}
render() {
return
}
}
export default Test;
~~~
And it is same when I use constructor style.
I am using the latest eslint and etc.
@mytharcher it鈥檚 an antipattern to pass around the entire props or state objects; and it basically prevents any form of static analysis on it. Destructure it first, and explicitly pass the members you need.
Most helpful comment
sure!
1697