HI ALL,
I found a problem with react/no-unused-prop-types rule.
When I use {...this.state} syntax in React component, the rule can't find the unused prop.
I don't know is this a bug with eslint-plugin-react?
Please Help. Thanks.
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import logo from './logo.svg';
import './App.css';
class App extends Component {
static propTypes = {
bar: PropTypes.string.isRequired,
};
state = {
style: { color: 'red' },
};
render() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
// when I add `{...this.state}`, the rule is no working
<h1 className="App-title" {...this.state} >Welcome to React</h1>
</header>
<p className="App-intro">
To get started, edit <code>src/App.js</code> and save to reload.
</p>
</div>
);
}
}
export default App;
{
"extends": "react-app",
"rules": {
"react/no-unused-prop-types": [
"error",
{
"customValidators": [],
"skipShapeProps": true
}
]
}
}
https://github.com/zhaozhiming/eslint-plugin-react-no-unused-prop-types
Have to see that: https://github.com/yannickcr/eslint-plugin-react/issues/1094
Hello, what is the current status with this issue?
The issue is that you shouldn't be interacting with props, state, or context as an object - passing it around, or spreading it. You should be explicitly destructuring only the properties you need out of them, and then work with those.
This is because of all of static analysis, performance, and code clarity.
The solution to this issue is for the plugin to treat all state fields as used when this.state is spread; but the better solution is to avoid doing that in the first place.
In my case rule doesn't work if component contains spread operator with any object, not only state or props.
My mistake, it actually doesn't work with spread in props.
But what should I do in this case? In Header I just want one prop title and rest props I want to pass through to another component, without describing it in Header's propTypes.
const React = require('react');
const PropTypes = require('prop-types');
function Header({title, ...props}) {
return (
<div {...props}>
<div>
{title}
</div>
</div>
);
}
Header.propTypes = {
title: PropTypes.string.isRequired,
foo: PropTypes.string.isRequired
};
module.exports = Header;
@fleg you should explicitly const { title, foo } = props and pass each of them explicitly.
Here I've got another case, which has nothing to do with spreading the whole props, but only one prop:
const React = require('react');
const PropTypes = require('prop-types');
export class MyComponent extends PureComponent {
static propTypes = {
selectedId: PropTypes.string.isRequired,
readonly: PropTypes.bool.isRequired,
options: PropTypes.arrayOf(PropTypes.object).isRequired,
};
render() {
const { options } = this.props;
return (
<div>
<div {...options} />
</div>
);
}
}
I explicitly get options from this.props first and spread only it. But eslint doesn't catch selectedId and readonly as unused props.