Error de reacción eslint que falta en la validación de accesorios

87

Tengo el siguiente código, eslint throw:

react / prop-types onClickOut; falta en la validación de accesorios

niños reaccionar / prop-tipos; falta en la validación de accesorios

propTypes se definió pero eslint no lo reconoce.

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,
  }
}
cristian camilo cedeño gallego
fuente
Tal vez la mejor manera de escribir:const { children, onClickOut, ...filteredProps } = this.props;
horyd
¿Está utilizando babel-eslint?
Timo
@horyd not, si lo hago eslint throw no-unused-vars onClickOut está definido pero nunca se usa
cristian camilo cedeño gallego
intenta definirlo como:static get propTypes() { return { children: PropTypes.any, onClickOut: PropTypes.func }; }
Omri Aharon
sí @TimoSta uso babel-eslint
cristian camilo cedeño gallego

Respuestas:

87

Debe definir propTypescomo un captador estático si lo desea dentro de la declaración de clase:

static get propTypes() { 
    return { 
        children: PropTypes.any, 
        onClickOut: PropTypes.func 
    }; 
}

Si desea definirlo como un objeto, debe definirlo fuera de la clase, así:

IxClickOut.propTypes = {
    children: PropTypes.any,
    onClickOut: PropTypes.func,
};

También es mejor si importa tipos de prop de prop-types, no react , de lo contrario verá advertencias en la consola (como preparación para React 16 ):

import PropTypes from 'prop-types';
Omri Aharon
fuente
1
Depende de la configuración de Babel, no es necesario que sea mejor si está utilizando el complemento de propiedades estáticas.
Dave Newton
Gracias. La primera opción arroja el mismo error, la segunda opción resuelve el problema pero no entiendo por qué definir como atributo de clase arroja un error en este caso. Nota: tengo otros componentes que funcionan bien definiendo como atributo de clase
cristian camilo cedeño gallego
1
No estoy seguro de por qué uno falla y el otro funciona. Pensé que tenía que definirse estáticamente en una clase de cualquier manera, tal vez estaba equivocado.
Omri Aharon
14

Parece que el problema está en eslint-plugin-react.

No puede detectar correctamente en qué accesorios se mencionaron propTypessi ha anotado objetos con nombre mediante la desestructuración en cualquier lugar de la clase.

Hubo un problema similar en el pasado

Alik
fuente
Estoy usando babel-eslint y habilito todas las etapas Nota: tengo otros componentes que funcionan bien definiendo como atributo de clase
cristian camilo cedeño gallego
@ cristiancamilocedeñogallego configuraciones de correos relevantes: package.json, .eslintrcEs difícil saber por qué no se recupera propTypes
Alik
1
entonces el problema está en la anotación de flujo enhandleClick
Alik
sí @alik se eliminó la anotación de flujo y funciona bien
cristian camilo cedeño gallego
7

Me encontré con este problema en los últimos días. Como dijo Omri Aharon en su respuesta anterior, es importante agregar definiciones para sus tipos de accesorios similares a:

SomeClass.propTypes = {
    someProp: PropTypes.number,
    onTap: PropTypes.func,
};

No olvide agregar las definiciones de accesorios fuera de su clase. Lo colocaría justo debajo / encima de mi clase. Si no está seguro de cuál es su tipo de variable o sufijo para su PropType (por ejemplo: PropTypes.number), consulte esta referencia de npm . Para usar PropTypes, debe importar el paquete:

import PropTypes from 'prop-types';

Si obtiene el error de pelusa: someProp is not required, but has no corresponding defaultProps declarationtodo lo que tiene que hacer es agregar .isRequiredal final de la definición de su prop así:

SomeClass.propTypes = {
    someProp: PropTypes.number.isRequired,
    onTap: PropTypes.func.isRequired,
};

O agregue valores de propiedad predeterminados como este:

SomeClass.defaultProps = {
    someProp: 1
};

Si usted es como yo, sin experiencia o no están familiarizados con reactjs, también puede obtener este error: Must use destructuring props assignment. Para corregir este error, defina sus accesorios antes de usarlos. Por ejemplo:

const { someProp } = this.props;
airvine
fuente
4

Sé que esta respuesta es ridícula, pero considere simplemente deshabilitar esta regla hasta que se resuelvan los errores o haya actualizado sus herramientas:

/* eslint-disable react/prop-types */ // TODO: upgrade to latest craco+eslint or Next.js?

O deshabilite todo el proyecto en su eslintrc:

"rules": {
  "react/prop-types": "off"
}
Devin G Rhode
fuente
1
La sintaxis real para deshabilitar esta regla es: "react / prop-types": "off"
Ken A Collins
Gracias, esto también es lo que usé en eslintrc en la sección de reglas
iBobb
3

el problema está en la anotación de flujo en handleClick, eliminé esto y funciona bien gracias @alik

cristian camilo cedeño gallego
fuente
2

Problema: 'id1' falta en la validación de accesorios, eslintreact / prop-types

<div id={props.id1} >
    ...
</div>

La siguiente solución funcionó, en un componente de función:

let { id1 } = props;

<div id={id1} >
    ...
</div>

Espero que ayude.

Manohar Reddy Poreddy
fuente
1

Para mí, actualizar eslint-plugin-react a la última versión 7.21.5 solucionó esto

Siphenathi
fuente