Brak błędu React eslint podczas sprawdzania poprawności właściwości

87

Mam następny kod, rzut eslint:

reaguj / prop-types onClickOut; brakuje podczas sprawdzania poprawności rekwizytów

dzieci reagujące / typu prop; brakuje podczas sprawdzania poprawności rekwizytów

propTypes został zdefiniowany, ale eslint go nie rozpoznaje.

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
źródło
Najlepiej const { children, onClickOut, ...filteredProps } = this.props;
chyba
Czy używasz babel-eslint?
Timo
@horyd not, if I do it eslint throw no-unused-vars onClickOut jest zdefiniowany, ale nigdy nie jest używany
cristian camilo cedeño gallego
spróbuj zdefiniować to jako:static get propTypes() { return { children: PropTypes.any, onClickOut: PropTypes.func }; }
Omri Aharon
yes @TimoSta i use babel-eslint
cristian camilo cedeño gallego.

Odpowiedzi:

87

Musisz zdefiniować propTypesjako statyczny getter, jeśli chcesz go wewnątrz deklaracji klasy:

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

Jeśli chcesz zdefiniować go jako obiekt, musisz zdefiniować go poza klasą, na przykład:

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

Lepiej też, jeśli importujesz typy właściwości z prop-types, a nie react , w przeciwnym razie zobaczysz ostrzeżenia w konsoli (jako przygotowanie do React 16 ):

import PropTypes from 'prop-types';
Omri Aharon
źródło
1
Zależy od konfiguracji Babel, nie musi być lepsza, jeśli używasz wtyczki właściwości statycznych.
Dave Newton,
Dzięki. Pierwsza opcja generuje ten sam błąd, druga opcja rozwiązuje problem, ale nie rozumiem, dlaczego zdefiniowanie jako atrybutu klasy powoduje w tym przypadku błąd. Uwaga: mam inne komponenty, które działają dobrze, definiując jako atrybut klasy
cristian camilo cedeño gallego
1
Nie wiem, dlaczego jeden zawodzi, a drugi działa. Myślałem, że tak czy inaczej trzeba to zdefiniować statycznie w klasie, może się myliłem.
Omri Aharon
14

Wygląda na to, że problem tkwi w eslint-plugin-react.

Nie może poprawnie wykryć, o których rekwizytach wspomniano, propTypesjeśli dodałeś adnotacje do nazwanych obiektów poprzez destrukturyzację w dowolnym miejscu w klasie.

W przeszłości był podobny problem

Alik
źródło
Używam babel-eslint i włączam wszystkie etapy Uwaga: Mam inne komponenty, które działają dobrze, definiując jako atrybut klasy
cristian camilo cedeño gallego
@ cristiancamilocedeñogallego pocztowych odpowiednich configs: package.json, .eslintrcTrudno powiedzieć, dlaczego nie podnieść propTypes
Alik
1
więc problem tkwi w opisie przepływu whandleClick
Alik
tak @alik został usunięty z adnotacji przepływu i działa dobrze
cristian camilo cedeño gallego
7

Napotkałem ten problem w ciągu ostatnich kilku dni. Jak powiedział Omri Aharon w swojej odpowiedzi powyżej, ważne jest, aby dodać definicje typów rekwizytów podobne do:

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

Nie zapomnij dodać definicji właściwości poza klasą. Umieściłbym to tuż poniżej / powyżej mojej klasy. Jeśli nie masz pewności, jaki typ zmiennej lub sufiks jest dla Twojego PropType (np. PropTypes.number), zapoznaj się z tym odniesieniem npm . Aby użyć PropTypes, musisz zaimportować pakiet:

import PropTypes from 'prop-types';

Jeśli pojawi się błąd lintingu: someProp is not required, but has no corresponding defaultProps declarationwszystko, co musisz zrobić, to dodać .isRequiredna końcu definicji właściwości w następujący sposób:

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

LUB dodaj domyślne wartości właściwości, takie jak:

SomeClass.defaultProps = {
    someProp: 1
};

Jeśli coś takiego jak ja, niedoświadczony lub znają reactjs, można również uzyskać ten błąd: Must use destructuring props assignment. Aby naprawić ten błąd, zdefiniuj swoje właściwości, zanim zostaną użyte. Na przykład:

const { someProp } = this.props;
airvine
źródło
5

Wiem, że ta odpowiedź jest niedorzeczna, ale rozważ wyłączenie tej reguły, dopóki błędy nie zostaną rozwiązane lub nie zaktualizujesz swoich narzędzi:

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

Lub wyłącz cały projekt w swoim eslintrc:

"rules": {
  "react/prop-types": "off"
}
Devin G Rhode
źródło
1
Rzeczywista składnia wyłączania tej reguły to: "reaguj / prop-typy": "wyłącz"
Ken A Collins,
Dzięki temu też użyłem w eslintrc w sekcji z zasadami
iBobb
3

problem dotyczy adnotacji przepływu w handleClick, usunąłem to i działa dobrze, dzięki @alik

cristian camilo cedeño gallego
źródło
2

Problem: brak atrybutu „id1” w walidacji właściwości, eslintreact / prop-types

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

Poniższe rozwiązanie zadziałało, w komponencie funkcyjnym:

let { id1 } = props;

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

Mam nadzieję, że to pomoże.

Manohar Reddy Poreddy
źródło
1

Jak dla mnie, aktualizacja eslint-plugin-act do najnowszej wersji 7.21.5 naprawiła ten problem

Siphenathi
źródło