Ich habe die folgende Komponente, die einen no-shadow
ESlint-Fehler auf dem auslöst FilterButton
props
.
import { setFilter } from '../actions/filter';
function FilterButton({ setFilter }) {
return (
<button onClick={setFilter}>Click</button>
);
}
export default connect(null, { setFilter })(FilterButton);
Wie kann ich die Warnung vermeiden, während sowohl mapDispatchToProps
die präzise Syntax als auch die ESlint-Regel beibehalten werden?
Ich weiß, dass ich einen Kommentar hinzufügen kann, um die Warnung zu unterdrücken, aber es scheint überflüssig und mühsam, dies für alle Komponenten zu tun.
javascript
reactjs
redux
eslint
react-redux
Kerumen
quelle
quelle
setFilter
(FilterButton({ setFilter })
inFilterButton({ setFilter })
) umbenennen . Es ist sinnvoll, weil die Funktionen inFilterButton
den Requisiten tatsächlich das Original sind,setFilter
an das diedispatch
Funktion gebunden ist.function FilterButton({ setFilter }) {
und umzubenennen<button onClick={setFilter}>Click</button>
. Können Sie Ihre Frage mit dem bearbeiteten Code aktualisieren?function FilterButton({ setFilter })
da es mit dem Namen der Requisite übereinstimmen muss, diesetFilter
tatsächlich ist.export default connect(null, {filter: setFilter})(FilterButton);
und dann einfach darüberfunction FilterButton ({filter}) {
(oder welchen neuen Variablennamen Sie bevorzugen). Auf diese Weise schattieren Sie die Variable nicht im oberen Bereich, und das ist klar, wenn Sie sich den Code ansehen.Antworten:
Hier gibt es vier Möglichkeiten:
1. Deaktivieren Sie die Regel.
Warum?
Dies ist der einfachste Weg, um den ESLint-Fehler zu vermeiden.
Warum nicht?
Die No-Shadow-Regel hilft, einen sehr häufigen Fehler bei der Verwendung zu vermeiden
react-redux
. Das heißt, der Versuch, die rohe, nicht verbundene Aktion aufzurufen (die nicht automatisch ausgelöst wird).Mit anderen Worten, wenn Sie keine Destrukturierung verwenden und die Aktion von Requisiten abrufen
setFilter()
würden , würde die Aktion nicht ausgelöst (da Sie die importierte Aktion direkt aufrufen würden, anstatt die verbundene Aktion über Requisiten über aufzurufenprops.setFilter()
, diereact-redux
automatisch für Sie versendet ).Wenn Sie die variable Schattierung bereinigen , werden Sie und / oder Ihre IDE den Fehler mit größerer Wahrscheinlichkeit erkennen.
Wie?
Das Hinzufügen einer
eslintConfig
Eigenschaft zu Ihrerpackage.json
Datei ist eine Möglichkeit, dies zu tun ."eslintConfig": { "rules": { "no-shadow": "off", } }
2. Weisen Sie die Variable beim Übergeben neu zu
connect()
.Warum?
Sie profitieren von der Sicherheit der No-Shadow-Regel. Wenn Sie sich für die Einhaltung einer Namenskonvention entscheiden, ist diese sehr explizit.
Warum nicht?
Es führt Boilerplate ein.
Wenn Sie keine Namenskonvention verwenden, müssen Sie jetzt für jede Aktion alternative Namen (die immer noch sinnvoll sind) erstellen. Und es besteht die Möglichkeit, dass dieselben Aktionen in verschiedenen Komponenten unterschiedlich benannt werden, was es schwieriger macht, sich mit den Aktionen selbst vertraut zu machen.
Wenn Sie eine Namenskonvention verwenden, werden Namen lang und wiederholen sich.
Wie?
Ohne Namenskonvention:
import { setFilter } from '../actions/filter'; function FilterButton({ filter }) { return ( <button onClick={filter}>Click</button> ); } export default connect(null, { filter: setFilter })(FilterButton);
Mit Namenskonvention:
import { setFilter, clearFilter } from '../actions/filter'; function FilterButton({ setFilterConnect, clearFilterConnect }) { return ( <button onClick={setFilterConnect} onBlur={clearFilterConnect}>Click</button> ); } export default connect(null, { setFilterConnect: setFilter, clearFilterConnect: clearFilter, })(FilterButton);
3. Zerstören Sie keine Aktionen von Requisiten.
Warum?
Wenn Sie die Methode off des Requisitenobjekts explizit verwenden, müssen Sie sich zunächst nicht um das Abschatten kümmern.
Warum nicht?
Das Vorbereiten aller Ihrer Aktionen mit
props
/this.props
wiederholt sich (und ist inkonsistent, wenn Sie alle anderen Requisiten ohne Aktion zerstören).Wie?
import { setFilter } from '../actions/filter'; function FilterButton(props) { return ( <button onClick={props.setFilter}>Click</button> ); } export default connect(null, { setFilter })(FilterButton);
4. Importieren Sie das gesamte Modul.
Warum?
Es ist prägnant.
Warum nicht?
Andere Entwickler (oder Ihr zukünftiges Selbst) haben möglicherweise Probleme zu verstehen, was los ist. Abhängig von dem Styleguide, dem Sie folgen, verstoßen Sie möglicherweise gegen die No-Wildcard-Import-Regel .
Wie?
Wenn Sie einfach Aktionsersteller aus einem Modul übergeben:
import * as actions from '../actions/filter'; function FilterButton({ setFilter }) { return ( <button onClick={setFilter}>Click</button> ); } export default connect(null, actions)(FilterButton);
Wenn Sie mehrere Module übergeben, verwenden Sie die Objektdestrukturierung mit Restsyntax :
import * as filterActions from '../actions/filter'; import * as otherActions from '../actions/other'; // all exported actions from the two imported files are now available as props function FilterButton({ setFilter, clearFilter, setOther, clearOther }) { return ( <button onClick={setFilter}>Click</button> ); } export default connect(null, { ...filterActions, ...otherActions })(FilterButton);
Und da Sie in den Kommentaren eine Präferenz für die prägnante Syntax von ES6 erwähnt haben, können Sie auch die Pfeilfunktion mit einer impliziten Rückgabe einfügen:
import * as actions from '../actions/filter'; const FilterButton = ({ setFilter }) => <button onClick={setFilter}>Click</button>; export default connect(null, actions)(FilterButton);
quelle
Disable the rule
:)no-shadow
verhindert werden, dass die Raw-Aktion aufgerufen wird? Es wird ein Fehler ausgegeben, wenn Sie es richtig machen (vorausgesetzt, es handelt sich um zerstörte Requisiten), und NICHT, wenn Sie die Raw-Aktion aufrufen. Die Antwort von @GollyJer ist eine großartige Ergänzung und sollte dem ersten Teil dieser Antwort beigefügt werden. Alles in allem ist es sehr wahrscheinlich die beste Vorgehensweise.$
den Namen der Aktionen voranzustellen und die Kurzform mapDispatchToProps zu verwenden, aber ich habe$
selbst bei jQuery immer ein wenig Jarring gefunden .Eine fünfte Option:
5. Erlauben Sie eine bestimmte Ausnahme über
eslintrc
Regeln.module.exports = { rules: { 'no-shadow': [ 'error', { allow: ['setFilter'], }, ], } }
Warum?
Sie möchten kein variables Shadowing, können es aber in bestimmten Fällen nicht umgehen.
Warum nicht?
Sie möchten wirklich kein variables Shadowing in Ihrer Codebasis. 😝
quelle
Option Nummer sechs.
6. Deaktivieren Sie die Es-Lint-Regel für die bestimmte (n) Codezeile (n)
import { setFilter } from '../actions/filter'; // eslint-disable-next-line no-shadow function FilterButton({ setFilter }) { return ( <button onClick={setFilter}>Click</button> ); } export default connect(null, { setFilter })(FilterButton);
oder
import { setFilter } from '../actions/filter'; /* eslint-disable no-shadow */ function FilterButton({ setFilter }) { /* es-lint-enable */ return ( <button onClick={setFilter}>Click</button> ); } export default connect(null, { setFilter })(FilterButton);
Die zweite Möglichkeit, die Es-Lint-Regel vorübergehend zu deaktivieren, kann im Gegensatz zur ersten für mehrere Codezeilen verwendet werden. Es kann nützlich sein, wenn Sie mehr Argumente übergeben und diese in mehrere Codezeilen unterteilen.
Warum?
Dies ist eine einfache und geeignete Option für einige Anwendungsfälle (z. B. verwendet Ihr Team / Ihre Organisation bestimmte Es-Lint-Einstellungen und es wird davon abgeraten / verboten, diese Einstellungen zu ändern). Es deaktiviert den Es-Lint-Fehler in den Codezeilen, hat jedoch keinen Einfluss auf die
mapDispatchToProps
Syntax und die Regel ist außerhalb der Codezeilen weiterhin vollständig aktiv.Warum nicht?
Sie möchten nicht oder es ist Ihnen verboten, Ihren Code mit solchen Kommentaren aufzublähen. Sie wollen oder es ist Ihnen verboten, das Verhalten von Flusen zu beeinflussen.
quelle
Option 7 ...
7. Verwenden Sie Behälterkomponenten
Warum?
Es ist ein bekanntes Muster und Sie erhalten den zusätzlichen Vorteil, dass Sie Ihre Komponenten vom Redux-Speicher entkoppeln, sodass sie leichter wiederverwendet werden können.
Warum nicht?
Sie benötigen jetzt zwei Dateien pro Komponente.
Wie?
// FilterButton.jsx export default function FilterButton({ setFilter }) { return ( <button onClick={setFilter}>Click</button> ); }
// FilterButtonRedux.jsx import FilterButton from './FilterButton'; import { setFilter } from '../actions/filter'; export default connect(null, { setFilter })(FilterButton);
quelle
Ich habe 4. optimiert und erreicht, was ich Option 8 nennen möchte.
8. Importieren Sie Methoden unter einem anderen Namen
Warum?
Es hat die gleichen Vorteile wie das Importieren des gesamten Moduls, jedoch ohne Widerspruch zu anderen Regeln, z. B. Verwenden Sie keine Platzhalterimporte (Airbnb) .
Warum nicht?
Es wird eine unnötige Variablendeklaration hinzugefügt, die Verwirrung stiften kann.
Wie?
Für den Einzelmethodenfall
import { setFilter as setFilterConnect } from '../actions/filter'; function FilterButton({ setFilter }) { return <button onClick={setFilter}>Click</button>; } export default connect( null, { setFilter: setFilterConnect } )(FilterButton);
quelle
Mit der neuen Hooks-API in Version 7.1.0 können Sie die Variable entfernen und
mapDispatchToProps
insgesamt:import { useDispatch } from 'react-redux' import { setFilter } from '../actions/filter'; function FilterButton() { const dispatch = useDispatch() return ( <button onClick={dispatch(setFilter())}>Click</button> ); } export default FilterButton;
quelle