道具验证中缺少 React eslint 错误
React eslint error missing in props validation
我有下一段代码,eslint throw:
react/prop-types onClickOut; is missing in props validation
react/prop-types children; is missing in props validation
propTypes
已定义,但 eslint 无法识别它。
import React, { Component, PropTypes } from 'react';
class IxClickOut extends Component {
static propTypes = {
children: PropTypes.any,
onClickOut: PropTypes.func,
};
componentDidMount() {
document.getElementById('app')
.addEventListener('click', this.handleClick);
}
componentWillUnmount() {
document.getElementById('app')
.removeEventListener('click', this.handleClick);
}
handleClick = ({ target }: { target: EventTarget }) => {
if (!this.containerRef.contains(target)) {
this.props.onClickOut();
}
};
containerRef: HTMLElement;
render() {
const { children, ...rest } = this.props;
const filteredProps = _.omit(rest, 'onClickOut');
return (
<div
{...filteredProps}
ref={container => {
this.containerRef = container;
}}
>
{children}
</div>
);
}
}
export default IxClickOut;
package.json
{
"name": "verinmueblesmeteor",
"private": true,
"scripts": {
"start": "meteor run",
"ios": "NODE_ENV=developement meteor run ios"
},
"dependencies": {
"fine-uploader": "^5.10.1",
"foundation-sites": "^6.2.3",
"install": "^0.8.1",
"ix-gm-polygon": "^1.0.11",
"ix-type-building": "^1.4.4",
"ix-type-offer": "^1.0.10",
"ix-utils": "^1.3.7",
"keymirror": "^0.1.1",
"meteor-node-stubs": "^0.2.3",
"moment": "^2.13.0",
"npm": "^3.10.3",
"rc-slider": "^3.7.3",
"react": "^15.1.0",
"react-addons-pure-render-mixin": "^15.1.0",
"react-dom": "^15.1.0",
"react-fileupload": "^2.2.0",
"react-list": "^0.7.18",
"react-modal": "^1.4.0",
"react-redux": "^4.4.5",
"react-router": "^2.6.0",
"react-styleable": "^2.2.4",
"react-textarea-autosize": "^4.0.4",
"redux": "^3.5.2",
"redux-form": "^5.3.1",
"redux-thunk": "^2.1.0",
"rxjs": "^5.0.0-beta.9",
"rxjs-es": "^5.0.0-beta.9",
"socket.io": "^1.4.8"
},
"devDependencies": {
"autoprefixer": "^6.3.6",
"babel-eslint": "^6.0.4",
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-preset-es2015": "^6.9.0",
"babel-preset-react": "^6.5.0",
"babel-preset-stage-0": "^6.5.0",
"core-js": "^2.0.0",
"cssnano": "^3.7.1",
"eslint": "^2.12.0",
"eslint-config-airbnb": "^9.0.1",
"eslint-import-resolver-meteor": "^0.2.3",
"eslint-plugin-import": "^1.8.1",
"eslint-plugin-jsx-a11y": "^1.2.2",
"eslint-plugin-react": "^5.1.1",
"node-sass": "^3.8.0",
"postcss-cssnext": "^2.6.0",
"sasslets-animate": "0.0.4"
},
"cssModules": {
"ignorePaths": [
"node_modules"
],
"jsClassNamingConvention": {
"camelCase": true
},
"extensions": [
"scss",
"sass"
],
"postcssPlugins": {
"postcss-modules-values": {},
"postcss-modules-local-by-default": {},
"postcss-modules-extract-imports": {},
"postcss-modules-scope": {},
"autoprefixer": {}
}
}
}
.babelrc
{
"presets": [
"es2015",
"react",
"stage-0"
],
"whitelist": [
"es7.decorators",
"es7.classProperties",
"es7.exportExtensions",
"es7.comprehensions",
"es6.modules"
],
"plugins": ["transform-decorators-legacy"]
}
.eslintrc
{
"parser": "babel-eslint",
"extends": "airbnb",
"rules": {
"no-underscore-dangle": ["error", { "allow": [_id, b_codes_id] }],
},
"settings": {
"import/resolver": "meteor"
},
"globals": {
"_": true,
"CSSModule": true,
"Streamy": true,
"ReactClass": true,
"SyntheticKeyboardEvent": true,
}
}
如果你想在 class 声明中,你需要将 propTypes
定义为静态 getter:
static get propTypes() {
return {
children: PropTypes.any,
onClickOut: PropTypes.func
};
}
如果要定义为对象,需要在class之外定义,像这样:
IxClickOut.propTypes = {
children: PropTypes.any,
onClickOut: PropTypes.func,
};
此外,如果您从 prop-types
、 而不是 react
导入道具类型会更好,否则您会在控制台中看到警告(作为准备 React 16):
import PropTypes from 'prop-types';
看来问题出在eslint-plugin-react
.
如果您在 class.
中的任何地方通过解构注释命名对象,则无法正确检测 propTypes
中提到的道具
问题出在 handleClick 的流注释中,我删除了它并且工作正常
谢谢@alik
我 运行 过去几天一直在关注这个问题。正如 Omri Aharon 在上面的回答中所说,为您的道具类型添加类似于以下内容的定义很重要:
SomeClass.propTypes = {
someProp: PropTypes.number,
onTap: PropTypes.func,
};
不要忘记在 class 之外添加道具定义。我会把它放在 below/above 我的 class 右边。如果您不确定您的 PropType 的变量类型或后缀是什么(例如:PropTypes.number),请参阅此 npm reference。要使用 PropTypes,您必须导入包:
import PropTypes from 'prop-types';
如果你得到 linting 错误:someProp is not required, but has no corresponding defaultProps declaration
你所要做的就是将 .isRequired
添加到你的 prop 定义的末尾,如下所示:
SomeClass.propTypes = {
someProp: PropTypes.number.isRequired,
onTap: PropTypes.func.isRequired,
};
或像这样添加默认属性值:
SomeClass.defaultProps = {
someProp: 1
};
如果你和我一样,没有经验或不熟悉 reactjs,你也可能会得到这个错误:Must use destructuring props assignment
。要修复此错误,请在使用道具之前定义它们。例如:
const { someProp } = this.props;
问题:道具验证中缺少 'id1',eslintreact/prop-types
<div id={props.id1} >
...
</div>
以下解决方案在函数组件中有效:
let { id1 } = props;
<div id={id1} >
...
</div>
希望对您有所帮助。
我知道这个答案很荒谬,但请考虑禁用此规则,直到错误被解决或您升级了您的工具:
/* eslint-disable react/prop-types */ // TODO: upgrade to latest eslint tooling
或者在你的 eslintrc 中禁用 project-wide:
"rules": {
"react/prop-types": "off"
}
对我来说,将 eslint-plugin-react 升级到最新版本 7.21.5 修复了这个问题
功能性 React 组件。定义为对象。我收到此错误是因为我从另一个名称略有不同的对象复制并粘贴了该对象,而忘记更改 proptypes 对象的名称。
FooterIcons.propTypes = {} -> FooterIcon.propTypes
PropTypes 检查是个好东西,不建议通过设置忽略
您可以使用 vscode React PropTypes 生成扩展自动生成 propTypes:
- Select 您的组件名称
- 按命令 + 。 (Windows 是 Ctrl + 。)显示代码操作和 select PropTypesGenerate,或者在 macOS
- 输入 propType 以替换默认类型
我发现 eslint 在我自己从事的项目中过于严格,但是对于这个错误,我通过定义我的接口然后实现它来修复它:
interface myInterface: {
test: string
}
const MyComponent: React.FC<myInterface> = (props: myInterface) => {
安装 prop-types 包 - npm i prop-types --save
导入它-
import PropTypes from 'prop-types';
然后指定道具,我是这样实现的-
export default function Text({ children }) {
Text.propTypes = {
children: PropTypes.node.isRequired,
};
return (
<VStyle className="para">
<p>{children}</p>
</VStyle>
);
}
同时将此添加到您的 eslintrc.json 或 .js 文件
"rules": {
"react/prop-types": "off"
}
从类似的问题中复制我的答案:
eslint-plugin-react@^7.25.0
似乎有 resolved 那些使用 React.FC<IProps>
和 react/prop-types
验证规则的问题。
所以不用
const Example: React.FC<IProps> = (props: IProps) => ...
更新后现在可以正常工作了
const Example: React.FC<IProps> = (props) => ...
而不是禁用prop-types
规则,我们可以引入children 属性作为组件道具的一部分,例如:
import React, { Component } from 'react';
export default class ErrorBoundary extends Component<{ children: React.ReactNode }> {
constructor(props: { children: React.ReactNode }) {
super(props);
this.state = { error: null, errorInfo: null };
}
componentDidCatch(error: Readonly<unknown>, errorInfo: Readonly<unknown>): void {
this.setState({ error, errorInfo });
}
render(): React.ReactElement | React.ReactNode {
const { children } = this.props;
const { error, errorInfo } = this.state as Readonly<Record<string, { componentStack: string }>>;
if (errorInfo)
return (
<details>
<h3>Oops, error detected.</h3>
<p>{error?.toString()}</p>
<p>{errorInfo?.componentStack}</p>
</details>
);
return children;
}
}
以上是典型的eslint
错误消失的例子~~
不愁开心~~
在新版本的 React 和 Next.js 上,您可以简单地导入 PropTypes,如下所示,
import PropTypes from "prop-types";
并在文件底部添加 defaultProps 和 propTypes,例如,
Post.defaultProps = {
posts: "",
};
Post.propTypes = {
posts: PropTypes.string,
};
export default Post;
它应该可以解决您的 eslint 警告。
我有下一段代码,eslint throw:
react/prop-types onClickOut; is missing in props validation
react/prop-types children; is missing in props validation
propTypes
已定义,但 eslint 无法识别它。
import React, { Component, PropTypes } from 'react';
class IxClickOut extends Component {
static propTypes = {
children: PropTypes.any,
onClickOut: PropTypes.func,
};
componentDidMount() {
document.getElementById('app')
.addEventListener('click', this.handleClick);
}
componentWillUnmount() {
document.getElementById('app')
.removeEventListener('click', this.handleClick);
}
handleClick = ({ target }: { target: EventTarget }) => {
if (!this.containerRef.contains(target)) {
this.props.onClickOut();
}
};
containerRef: HTMLElement;
render() {
const { children, ...rest } = this.props;
const filteredProps = _.omit(rest, 'onClickOut');
return (
<div
{...filteredProps}
ref={container => {
this.containerRef = container;
}}
>
{children}
</div>
);
}
}
export default IxClickOut;
package.json
{
"name": "verinmueblesmeteor",
"private": true,
"scripts": {
"start": "meteor run",
"ios": "NODE_ENV=developement meteor run ios"
},
"dependencies": {
"fine-uploader": "^5.10.1",
"foundation-sites": "^6.2.3",
"install": "^0.8.1",
"ix-gm-polygon": "^1.0.11",
"ix-type-building": "^1.4.4",
"ix-type-offer": "^1.0.10",
"ix-utils": "^1.3.7",
"keymirror": "^0.1.1",
"meteor-node-stubs": "^0.2.3",
"moment": "^2.13.0",
"npm": "^3.10.3",
"rc-slider": "^3.7.3",
"react": "^15.1.0",
"react-addons-pure-render-mixin": "^15.1.0",
"react-dom": "^15.1.0",
"react-fileupload": "^2.2.0",
"react-list": "^0.7.18",
"react-modal": "^1.4.0",
"react-redux": "^4.4.5",
"react-router": "^2.6.0",
"react-styleable": "^2.2.4",
"react-textarea-autosize": "^4.0.4",
"redux": "^3.5.2",
"redux-form": "^5.3.1",
"redux-thunk": "^2.1.0",
"rxjs": "^5.0.0-beta.9",
"rxjs-es": "^5.0.0-beta.9",
"socket.io": "^1.4.8"
},
"devDependencies": {
"autoprefixer": "^6.3.6",
"babel-eslint": "^6.0.4",
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-preset-es2015": "^6.9.0",
"babel-preset-react": "^6.5.0",
"babel-preset-stage-0": "^6.5.0",
"core-js": "^2.0.0",
"cssnano": "^3.7.1",
"eslint": "^2.12.0",
"eslint-config-airbnb": "^9.0.1",
"eslint-import-resolver-meteor": "^0.2.3",
"eslint-plugin-import": "^1.8.1",
"eslint-plugin-jsx-a11y": "^1.2.2",
"eslint-plugin-react": "^5.1.1",
"node-sass": "^3.8.0",
"postcss-cssnext": "^2.6.0",
"sasslets-animate": "0.0.4"
},
"cssModules": {
"ignorePaths": [
"node_modules"
],
"jsClassNamingConvention": {
"camelCase": true
},
"extensions": [
"scss",
"sass"
],
"postcssPlugins": {
"postcss-modules-values": {},
"postcss-modules-local-by-default": {},
"postcss-modules-extract-imports": {},
"postcss-modules-scope": {},
"autoprefixer": {}
}
}
}
.babelrc
{
"presets": [
"es2015",
"react",
"stage-0"
],
"whitelist": [
"es7.decorators",
"es7.classProperties",
"es7.exportExtensions",
"es7.comprehensions",
"es6.modules"
],
"plugins": ["transform-decorators-legacy"]
}
.eslintrc
{
"parser": "babel-eslint",
"extends": "airbnb",
"rules": {
"no-underscore-dangle": ["error", { "allow": [_id, b_codes_id] }],
},
"settings": {
"import/resolver": "meteor"
},
"globals": {
"_": true,
"CSSModule": true,
"Streamy": true,
"ReactClass": true,
"SyntheticKeyboardEvent": true,
}
}
如果你想在 class 声明中,你需要将 propTypes
定义为静态 getter:
static get propTypes() {
return {
children: PropTypes.any,
onClickOut: PropTypes.func
};
}
如果要定义为对象,需要在class之外定义,像这样:
IxClickOut.propTypes = {
children: PropTypes.any,
onClickOut: PropTypes.func,
};
此外,如果您从 prop-types
、 而不是 react
导入道具类型会更好,否则您会在控制台中看到警告(作为准备 React 16):
import PropTypes from 'prop-types';
看来问题出在eslint-plugin-react
.
如果您在 class.
中的任何地方通过解构注释命名对象,则无法正确检测propTypes
中提到的道具
问题出在 handleClick 的流注释中,我删除了它并且工作正常 谢谢@alik
我 运行 过去几天一直在关注这个问题。正如 Omri Aharon 在上面的回答中所说,为您的道具类型添加类似于以下内容的定义很重要:
SomeClass.propTypes = {
someProp: PropTypes.number,
onTap: PropTypes.func,
};
不要忘记在 class 之外添加道具定义。我会把它放在 below/above 我的 class 右边。如果您不确定您的 PropType 的变量类型或后缀是什么(例如:PropTypes.number),请参阅此 npm reference。要使用 PropTypes,您必须导入包:
import PropTypes from 'prop-types';
如果你得到 linting 错误:someProp is not required, but has no corresponding defaultProps declaration
你所要做的就是将 .isRequired
添加到你的 prop 定义的末尾,如下所示:
SomeClass.propTypes = {
someProp: PropTypes.number.isRequired,
onTap: PropTypes.func.isRequired,
};
或像这样添加默认属性值:
SomeClass.defaultProps = {
someProp: 1
};
如果你和我一样,没有经验或不熟悉 reactjs,你也可能会得到这个错误:Must use destructuring props assignment
。要修复此错误,请在使用道具之前定义它们。例如:
const { someProp } = this.props;
问题:道具验证中缺少 'id1',eslintreact/prop-types
<div id={props.id1} >
...
</div>
以下解决方案在函数组件中有效:
let { id1 } = props;
<div id={id1} >
...
</div>
希望对您有所帮助。
我知道这个答案很荒谬,但请考虑禁用此规则,直到错误被解决或您升级了您的工具:
/* eslint-disable react/prop-types */ // TODO: upgrade to latest eslint tooling
或者在你的 eslintrc 中禁用 project-wide:
"rules": {
"react/prop-types": "off"
}
对我来说,将 eslint-plugin-react 升级到最新版本 7.21.5 修复了这个问题
功能性 React 组件。定义为对象。我收到此错误是因为我从另一个名称略有不同的对象复制并粘贴了该对象,而忘记更改 proptypes 对象的名称。
FooterIcons.propTypes = {} -> FooterIcon.propTypes
PropTypes 检查是个好东西,不建议通过设置忽略
您可以使用 vscode React PropTypes 生成扩展自动生成 propTypes:
- Select 您的组件名称
- 按命令 + 。 (Windows 是 Ctrl + 。)显示代码操作和 select PropTypesGenerate,或者在 macOS
- 输入 propType 以替换默认类型
我发现 eslint 在我自己从事的项目中过于严格,但是对于这个错误,我通过定义我的接口然后实现它来修复它:
interface myInterface: {
test: string
}
const MyComponent: React.FC<myInterface> = (props: myInterface) => {
安装 prop-types 包 - npm i prop-types --save
导入它-
import PropTypes from 'prop-types';
然后指定道具,我是这样实现的-
export default function Text({ children }) {
Text.propTypes = {
children: PropTypes.node.isRequired,
};
return (
<VStyle className="para">
<p>{children}</p>
</VStyle>
);
}
同时将此添加到您的 eslintrc.json 或 .js 文件
"rules": {
"react/prop-types": "off"
}
从类似的问题中复制我的答案:
eslint-plugin-react@^7.25.0
似乎有 resolved 那些使用 React.FC<IProps>
和 react/prop-types
验证规则的问题。
所以不用
const Example: React.FC<IProps> = (props: IProps) => ...
更新后现在可以正常工作了
const Example: React.FC<IProps> = (props) => ...
而不是禁用prop-types
规则,我们可以引入children 属性作为组件道具的一部分,例如:
import React, { Component } from 'react';
export default class ErrorBoundary extends Component<{ children: React.ReactNode }> {
constructor(props: { children: React.ReactNode }) {
super(props);
this.state = { error: null, errorInfo: null };
}
componentDidCatch(error: Readonly<unknown>, errorInfo: Readonly<unknown>): void {
this.setState({ error, errorInfo });
}
render(): React.ReactElement | React.ReactNode {
const { children } = this.props;
const { error, errorInfo } = this.state as Readonly<Record<string, { componentStack: string }>>;
if (errorInfo)
return (
<details>
<h3>Oops, error detected.</h3>
<p>{error?.toString()}</p>
<p>{errorInfo?.componentStack}</p>
</details>
);
return children;
}
}
以上是典型的eslint
错误消失的例子~~
不愁开心~~
在新版本的 React 和 Next.js 上,您可以简单地导入 PropTypes,如下所示,
import PropTypes from "prop-types";
并在文件底部添加 defaultProps 和 propTypes,例如,
Post.defaultProps = {
posts: "",
};
Post.propTypes = {
posts: PropTypes.string,
};
export default Post;
它应该可以解决您的 eslint 警告。