React: Hooks + mehrere Instanzen von React

Erstellt am 27. Okt. 2018  ·  285Kommentare  ·  Quelle: facebook/react

An Personen, die von der Suche kommen: Bitte lesen Sie zuerst diese Seite . Es enthält die gängigsten möglichen Korrekturen!

Möchten Sie eine Funktion anfordern oder einen Fehler melden?

Erweiterung

Wie ist das aktuelle Verhalten?

Ich hatte versehentlich mehrere Instanzen von React.

Beim Versuch, Hooks zu verwenden, wurde dieser Fehler angezeigt:
hooks can only be called inside the body of a function component

Was nicht richtig ist, da ich Funktionskomponenten verwendet habe. Ich habe eine Weile gebraucht, um die wahre Ursache des Problems zu finden.

Was ist das erwartete Verhalten?

Zeigt die richtige Fehlermeldung an. Erkennen Sie vielleicht, dass die App mehrere Instanzen von React hat, und sagen Sie, dass dies der Grund für Fehler sein könnte.

Hooks Discussion

Hilfreichster Kommentar

Ich hatte das gleiche Problem und habe es gelöst, indem ich hinzugefügt habe:

 alias: {
        react: path.resolve('./node_modules/react')
      }

in die Eigenschaft resolve in der Webpack-Konfiguration meiner Haupt-App.

Es war offensichtlich mein Fehler, zwei Kopien von React zu verwenden, aber ich stimme zu, dass es großartig wäre, wenn die Fehlermeldung besser wäre. Ich denke, das ist vielleicht ähnlich wie: https://github.com/facebook/react/issues/2402

Alle 285 Kommentare

Nur zur Verdeutlichung: Sie haben einen Hook (z. B. useState ) aus einem anderen react Modul importiert als dem, das zum Rendern der Komponente verwendet wurde?

Ich stimme zu, dass dies verwirrend ist. Ich bin mir jedoch nicht sicher, ob wir wissen können, ob ein anderes React-Modul gerendert wird. AFAIK versuchen wir, React so weit wie möglich isoliert auszuführen, damit mehrere React-Instanzen ohne Probleme im selben globalen Kontext arbeiten können.

Andernfalls könnten wir wahrscheinlich die Fehlermeldung aktualisieren und diesen Fall ebenfalls erwähnen, wenn es nicht zu verwirrend ist.

Ja, ich habe React1 === React2 verglichen und es war false (React1 stammt aus index.js und React2 stammt aus der Datei, die den Hook verwendet). In diesem Fall schlagen Hooks mit der obigen allgemeinen Fehlermeldung fehl.

Dieses Problem soll das Bewusstsein für diesen Fall schärfen und möglicherweise die Fehlermeldung auf irgendeine Weise verbessern, um Menschen zu helfen, die damit konfrontiert sind. Es ist aber wahrscheinlich sehr kantig.

Ja, ich habe versucht, ein Paket, das ich erstelle, mit npm zu verknüpfen . Es wirft den gleichen Fehler, da das andere Paket auch Hooks verwendet, aber mit seinem eigenen React. Ich musste mein Paket in NPM veröffentlichen und es dann direkt aus NPM importieren. Auf diese Weise war der Fehler weg, aber ich hoffe, dass dies behoben ist, da das Veröffentlichen eines Pakets ohne Testen offensichtlich schlecht ist

Lerna Monorepos leiden ebenfalls darunter, wenn ein benutzerdefinierter Hook in einem Paket definiert und von einem anderen verwendet wird, da die symbolisch verknüpften Abhängigkeiten ihre eigene Kopie von React verwenden.

Ich habe im Moment eine (hackige) Problemumgehung mit npm-link-shared und einem prestart npm-Skript, um die react -Abhängigkeit des einen Pakets im Wesentlichen durch einen Symlink zu dem anderen zu ersetzen, also verwenden sie dieselbe Instanz.

"prestart": "npm-link-shared ./node_modules/<other package>/node_modules . react"

Ich hatte das gleiche Problem und habe es gelöst, indem ich hinzugefügt habe:

 alias: {
        react: path.resolve('./node_modules/react')
      }

in die Eigenschaft resolve in der Webpack-Konfiguration meiner Haupt-App.

Es war offensichtlich mein Fehler, zwei Kopien von React zu verwenden, aber ich stimme zu, dass es großartig wäre, wenn die Fehlermeldung besser wäre. Ich denke, das ist vielleicht ähnlich wie: https://github.com/facebook/react/issues/2402

@mpeyper Es funktioniert. Danke

@apieceofbart Das hat bei mir funktioniert. Danke für den Vorschlag. 👍

Soweit ich weiß, tritt dieses Problem auf, wenn mehrere Kopien von React im selben Paket enthalten sind.

Ist dies auch ein Problem, wenn zwei separate Bundles mit ihren eigenen Kopien von React ihre eigenen React-Anwendungen auf separaten Dom-Elementen booten, wie hier beschrieben: https://medium.jonasbandi.net/hosting-multiple-react-applications-on- das-selbe-dokument-c887df1a1fcd

Ich denke, letzteres ist ein gängiges „Integrations“-Muster, das beispielsweise im Single-Spa-Meta-Framework (https://github.com/CanopyTax/single-spa) verwendet wird.

Ich habe dieses Problem auch mit genau denselben Reaktionsversionen, die Entwicklung von Hooks, die eigenständig veröffentlicht werden sollen, ist bei Verwendung npm-link . Bekomme die gleiche wenig hilfreiche hooks can only be called inside the body of a function component Nachricht. Die Alias-Lösung von @apieceofbart hat dies für mich gelöst. Vielen Dank!

Dasselbe Problem hier, wenn ich ein Paket zu meiner Hauptanwendung npm link mache. Ich konnte babel-plugin-module-resolver nicht zum Laufen bringen.
Es sagt:
Could not find module './node_module/react'
Das ist ärgerlich, weil es mich daran hindert, meine Komponente lokal zu testen, bevor ich sie veröffentliche.

Ich habe mein Problem behoben, indem ich das Caretzeichen in "react": "^16.7.0-alpha.2" entfernt habe
Hier ist der vollständige Kommentar: https://github.com/facebook/react/issues/14454#issuecomment -449585005

Ich verwende Yarn und habe dies behoben, indem ich die Auflösung in meinem package.json habe:

  "resolutions": {
    "**/react": "16.7.0-alpha.2",
    "**/react-dom": "16.7.0-alpha.2"
  },

Hier gilt das gleiche!!

Ich wollte hier nur eine Notiz für alle hinterlassen, die dieses Problem möglicherweise auf die gleiche Weise wie ich hatten.

Wir führen React und Rails mit dem Gem react-rails aus und rendern Komponenten direkt in Rails-Ansichten. Ich erhielt diesen Fehler jedes Mal, wenn eine neue Version der App gepusht wurde, weil Turbolinks das neue JS-Bundle aus dem <head> holte, das eine zusätzliche Instanz von React lud. Die Lösung bestand darin, Turbolinks eine vollständige Seite neu laden zu lassen, wenn festgestellt wird, dass sich das Bundle geändert hat: https://github.com/turbolinks/turbolinks#reloading -when-assets-change

Dies scheint es für uns gelöst zu haben.

Ich freue mich sehr darauf, Hooks endlich in Produktion zu bringen, und wir alle schulden allen, die das möglich gemacht haben, ein riesiges Dankeschön. Es macht _ tonnenweise _ Spaß, mit ihnen zu arbeiten, und sie haben meinen Code kürzer und aussagekräftiger gemacht.

Nur als Hinweis, dieses Problem ist in der veröffentlichten Version immer noch relevant, mit der gleichen wenig hilfreichen Fehlermeldung „Hooks können nur innerhalb des Körpers einer Funktionskomponente aufgerufen werden“.

Ist das etwas, das behoben werden kann? Ich stelle mir vor, dass es immer häufiger vorkommt, wenn mehr Entwickler beginnen, die neuen Funktionen zu implementieren, und eine klarere Fehlermeldung anstelle einer direkten "Korrektur" viel bewirken würde.

Nochmals vielen Dank für all die harte Arbeit und herzlichen Glückwunsch zur Veröffentlichung! Es ist wirklich eine erstaunliche Reihe von Funktionen.

Bearbeiten : Hätte sich die offenen PRs genauer ansehen sollen, habe gerade # 14690 gefunden, das dies anspricht. Danke @dreipunkt!

@taylorham Der Link im Commit zeigt noch auf nichts. Ich werde darauf warten, aber das ist ein Problem, das ich habe, seit ich Hooks in einem verknüpften _(ab npm link )_-Paket verwende, und es ist unmöglich, damit lokal zu arbeiten, ohne es zu veröffentlichen.
Nachdem ich mir mehrere Probleme angesehen hatte, dachte ich, dass dies ein Problem mit dem React-Hot-Loader war, der Komponenten zu Klassen kompilierte, aber selbst nachdem sie eine Version mit Hook-Unterstützung veröffentlicht hatten, schlägt es immer noch auf die gleiche Weise fehl.
Ich habe viele verschiedene Hacks ausprobiert, aber kein Glück. Ich weiß nicht, warum noch nicht alle von diesem Problem betroffen sind 🧐

@dotlouis Ja, es ist bisher nur eine aktualisierte Fehlermeldung und das Problem selbst ist immer noch ein Problem.

Das einzige, was für mich überhaupt funktioniert hat, ist, jede App, die ich entwickle, von der React -Instanz der Bibliothek abhängig zu machen, indem ich "react": "link:../my-library/node_modules/react" verwende.

  • Keine der vorgeschlagenen Auflösungen hat bei mir funktioniert, und ich habe alle ausprobiert
  • versuchen, auf einem Projekt zu installieren, das Kontext und viele HOCs implementiert
  • Ausgehend von einem leeren Projekt hat es funktioniert
  • Ich suche weiter nach der Ursache

[ok] Für mich ging es bei der Korrektur nicht um package.json oder andere doppelte Reaktionsursachen: Ich hatte einen globalen ThemeProvider über meiner App, der aus dem Kontext stammt. Es schien die einzige Lösung zu sein, es durch einen "useContext Hook" zu ersetzen (während es als funktionales comp umgeschrieben wurde).
Vielleicht gibt es ein Problem wann

<GoodOldContext iam={a class component}>
    <BrandNewHook>
             errors : Hooks can only be called inside the body of a function component #35
     </BrandnewHook>
</GooOldContext>
export withGoodOldContext.consumer(here component)

Ich entwickle eine Komponente, in der es einen Ordner example gibt, der create-react-app verwendet.

Wenn Sie dies in package.json tun, wurde dieses Problem für mich gelöst:

{
    ...
    "dependencies": {
        "my-component": "link:..",
        "react": "link:../node_modules/react",
        "react-dom": "link:../node_modules/react-dom",
        "react-scripts": "2.1.3"
    },
    ...
}

@taylorham @DylanVann Danke für eure Beiträge Jungs. Leider funktioniert es bei mir immer noch nicht.
Und ich konnte keine Dokumentation zu diesem link: -Protokoll finden, das Sie verwendet haben.
Im Grunde sagt es, dass "React-Spring" (eine andere Dep, die auch React als Abhängigkeit verwendet) react-dom nicht finden kann. Können Sie mir bitte eine Dokumentation über "react": "link:../some/path" zeigen?

Ich verwende auch das verknüpfte UI-Paket und konnte dieses Problem beheben.
Sie müssen React renderToString von der Benutzeroberfläche (verknüpftes Paket) exportieren.
Ich habe die Renderfunktion im verlinkten Paket erstellt.

Nur für einen besseren Kontext - https://github.com/facebook/react/issues/14257

Danke @theKashey. @gaearon scheint zu denken, dass es das normale Verhalten ist. Ich verstehe, dass React nicht zweimal geladen werden sollte, aber was ist dann die empfohlene Vorgehensweise, um mit einem verknüpften lokalen Paket zu arbeiten?

Ich hatte auch Probleme damit, dass Lerna-Arbeitsbereiche richtig mit Symlinks verknüpft wurden. Das war der Trick, den ich benutzt habe, um das zum Laufen zu bringen. Achten Sie darauf, danach npm install auszuführen.

"dependencies": {
    "react-dom": "file:../common/node_modules/react-dom",
    "react": "file:../common/node_modules/react"
}

Es gibt viele Möglichkeiten, es zu lösen, und Garnauflösungen würden normalerweise nicht helfen - es hängt eher mit dem "Bauwerkzeug" zusammen.

  • Verwenden Sie für Webpack aliases - nur ein "harter" Alias, der alles wie react in eine einzelne Datei duckt
  resolve: {
    extensions: ['.ts', '.tsx', '.js', '.jsx'],
    alias: {
     react: path.resolve(path.join(__dirname, './node_modules/react')),
   }
import {setAliases} from 'require-control';
setAliases({
  'react': path.resolve(path.join(__dirname, './node_modules/react'))
});
  • Verwenden Sie zum Scherz moduleNameMapper
"jest": {
    "moduleNameMapper": {
      "^react$": "<rootDir>/node_modules/$1",
    },

@theKashey danke für deine Erkenntnisse, das macht Sinn, wenn wir überlegen, wie die Modulauflösung erfolgt (unten, dann den Baum hinauf), aber aus Benutzersicht finde ich das nicht sehr praktisch. Wenn ich ein Paket npm link mache, würde ich erwarten, dass es funktioniert, ohne Abhängigkeiten explizit neu verbinden zu müssen. Dies macht die Entwicklung eines Pakets lokal ziemlich mühsam.

Dies ist ein Eckpfeiler, so funktioniert node_modules , deshalb haben Sie möglicherweise zwei Versionen eines Button in zwei verschiedenen Hauptversionen, und abhängige Module finden leicht das "richtige" Version eines Pakets.
So sollte es immer funktionieren.

Die Interna Node.js sind ziemlich einfach - versuchen Sie, eine Datei zu öffnen, die alle bekannten Präfixe (wie node_modules ) oder Erweiterungen (wie js , ts , json ) hinzufügt

yarn pnp wird das tun und könnte das Problem lösen. yarn workspaces , wodurch gemeinsam genutzte Pakete nach oben _hieben_ werden können, wird das Problem auch ohne "Magie" lösen.

npm workspaces ? Existiert gerade nicht.

Am Ende habe ich mein Projekt auf die Verwendung von Arbeitsbereichen umgestellt. Es löst dies, ohne Auflösungen verwenden zu müssen, und das Heben / die Struktur ist sowieso von Vorteil.

Dieser war ein Kopfkratzer. Ich habe die Einstellung „resolve.alias“ des Webpacks ausprobiert, aber sie hat nicht funktioniert, auch viele Einstellungen ausprobiert, aber leider nie wirklich zum Laufen gebracht, aber hier ist, wie ich es endlich geschafft habe, sie zum Laufen zu bringen:

Hier ist meine Ordnerstruktur:

Projekt
|
+-- node_modules
|
+-- bauen
| |
| +--index.js
|
+-- Beispiel (create-react-app)
| |
| +-- Paket.json

Ich musste meine package.json im Beispielordner ändern und im Wesentlichen die Reaktion aus den 'Haupt' node_modules des Projekts ziehen, basierend auf dem Vorschlag von @jmlivingston , so endet es:

  "dependencies": {
    "react": "file:../node_modules/react",
    "react-dom": "file:../node_modules/react-dom",
    "react-scripts": "2.1.5"
  },

Danach habe ich npm install und dann npm link , das hat funktioniert.

Hoffentlich kann dies jemand anderem helfen und Zeit sparen.

Also irgendeine Lösung für dieses Problem? Ich habe versucht, so viele Empfehlungen hier, wie ich kann und kein Glück. Ich verwende create-react-app und typescript. Verwendung von React/React-dom 16.8.3. Dies ist ein neues Projekt, das ich vor 2 Tagen erstellt habe, also ziemlich einfach. Ich verwende useSpring() und animation.div. Danke

@guru-florida verwendest du zufällig den React-Router?

Ich verwende denselben Stack wie Sie (Typescript & Create-React-App) und mein Problem mit dem Attribut render . Das Ändern in component hat den Zweck erfüllt.

Vor:

<Route path="/signup" render={SignUp} />

Nach dem:

<Route path="/signup" component={SignUp} />

Ich hoffe es hilft..!

@mikeyyyyyy Nein, React Router wird in diesem Fall nicht verwendet. Danke für den Tipp, denn ich war im letzten Projekt, in dem ich versucht habe, Spring zu verwenden, und hatte das gleiche Problem.

Ich hatte dieses Problem mit npm link (in einer Paket-App), das npm link .../whatever/node_modules/react scheint es nicht zu lösen, funktioniert aber gut mit Nicht-Hook-Komponenten

@tj Ich denke, du hast ein Problem mit ssr. Eine schnelle Problemumgehung besteht darin, Reaktionsfunktionen oder die gesamte Reaktion aus dem verknüpften Paket zu exportieren und in Ihr Serverpaket zu importieren

@seeden ahh Ich benutze kein SSR, nur ein SPA mit Paket. Ich habe intern ein ui -Paket für meine eigenen Sachen und eine App, an der ich arbeite, beide haben die gleiche react -Version, scheint seltsam, dass es ein Duplikat gibt, aber vielleicht ist das ein Paketproblem

@tj oh, ich verstehe. Dann viel Glück mit diesem sehr seltsamen Problem. Ich habe eine Woche damit verbracht

Also irgendeine Lösung für dieses Problem?

An sich gibt es hier kein Problem . Wie auf dieser Seite erklärt, benötigt React useState() Aufrufe, um sich auf demselben react Objekt wie das react Objekt zu befinden, wie es von innerhalb von react-dom "gesehen" wird. Wenn dies bei Ihnen nicht der Fall ist, bedeutet dies, dass Sie zwei Kopien von React auf der Seite bündeln – was an sich schon schlecht ist und auch einige andere Funktionen vor Hooks beschädigt. Sie werden es also trotzdem reparieren wollen. Diese Seite enthält allgemeine Möglichkeiten zur Diagnose, um das Problem zu beheben.

Wir lassen diese Diskussion offen, um bestimmte Problemumgehungen zu teilen, wenn Leute auf dieses Problem stoßen. Aber es ist kein Problem an sich, das von irgendjemandem außer Ihnen "behoben" werden kann.

Ich hatte dieses Problem mit npm-Link (in einer Paket-App), der npm-Link .../whatever/node_modules/react scheint es nicht zu lösen, funktioniert aber gut mit Nicht-Hook-Komponenten

Haben Sie etwas dagegen, eine kleine Repro-Hülle zu erstellen?

@gaearon reicht aus, sollte nächste Woche Zeit haben, ein bisschen mehr zu graben

Glücklicherweise hat require-control unser Problem mit dem statischen Kontext von yarn link + SSR + styled-components 4 behoben. Danke @theKashey 👍

Ich habe hier alles versucht und bin gescheitert. Es war eigentlich etwas anderes, das hier nicht dokumentiert ist. Es lag an der Groß-/Kleinschreibung der Reaktionsimporte . In einigen Fällen hatten wir:

import React from 'react'

Und bei anderen:

import React from 'React'

Auf einigen Dateisystemen (Unix, OSX) führt dies dazu, dass Webpack zwei Kopien von React instanziiert.

Dies verursachte extreme Verwirrung, da ich deutlich sehen konnte, dass wir nur eine Kopie von React haben; aber es war stattdessen die Art und Weise, wie wir es importierten.

Der Test auf die Reaktionsdokumentation läuft auch gut, da offensichtlich nur Kleinbuchstaben verwendet werden.

Das klingt so, als wäre es eine Erwähnung in den Dokumenten wert?

Für mich war der Grund für mehrere Instanzen von React das Webpack DllPlugin. Für meine Hersteller-DLL habe ich react und react-dom nicht in meine Eintragsliste aufgenommen, aber ich hatte andere Bibliotheken, die react oder react-dom erforderten meine DLL enthielt react und react-dom (eine schnelle Überprüfung der Manifest-JSON-Datei kann dies zeigen). Als ich also den Code ausführte und React in die Anwendung importierte, wurde es von node_modules , aber im Code der Anbieter war React aus ihrer DLL-Datei erforderlich.

Insgesamt : Seien Sie vorsichtig mit DLL-Dateien und stellen Sie sicher, dass Ihre enthaltenen Module keine zusätzlichen Abhängigkeiten enthalten, die Sie nicht benötigen, da Sie sie sonst doppelt importieren.

Ich konnte dies beheben, indem ich react-hot-loader auf 4.6.0 aktualisierte

das hat den Trick für das npm link -Zeug in Parcel gemacht:

"alias": {
        "react": "../ui/node_modules/react",
        "react-dom": "../ui/node_modules/react-dom"
    }

Ich bin mir nicht sicher, ob es das ist, was es für einen Produktions-Build zu verwenden versucht, scheint irgendwie hacky zu sein, aber es funktioniert zumindest für die Entwicklung

@theKashey OMG Mann, es funktioniert! Ich habe viele verschiedene Lösungen ausprobiert, die Leute in Bezug auf dieses Problem vorschlagen: Verstümmeln mit package.json Deps, Verfolgen von "zwei Reaktionen" über das Projekt hinweg, Prüfen, ob ich gegen die *Rule of Hooks' verstoße (was ich bin nicht), aber ich denke, dass Ihre Option mit:

alias: {
      react: path.resolve(path.join(__dirname, './node_modules/react')),
      'react-dom': path.resolve(path.join(__dirname, './node_modules/react-dom'))
    }

ermöglicht es uns, unser Projekt auf das nächste lvl zu verschieben, indem wir Hooks in unserer app-as-a-lib verwenden.

Dies ist die resultierende webpack.config.js

npm ls react

kehrt zurück

[email protected] D:\code\project
`-- (empty)

Für mich

console.log(window.React1 === window.React2) gibt wahr zurück
An diesem Punkt denke ich, dass es SSR ist, das das Problem verursacht

Aktualisieren. Es wurde tatsächlich durch das SSR-Verhalten von React-apollo verursacht (https://github.com/apollographql/react-apollo/issues/2541)
Ein Upgrade auf 2.3.1 hat es behoben

Hallo Leute, unser Team steht vor diesem Problem und hat einige Tage gebraucht, um es zu lösen.

die Arbeitslösungen für uns

Lösung A: Geben Sie die zu suchende Paketposition an, wie oben erwähnt

  alias: {
      react: path.resolve(path.join(__dirname, './node_modules/react')),
      'react-dom': path.resolve(path.join(__dirname, './node_modules/react-dom'))
    }

Lösung B: Verwenden Sie das Webpaket „ resolve.modules“ , um den richtigen Ordner „node_modules“ für die Suche nach Modulen zu priorisieren

Fallhintergrund und warum es passiert

Das Wichtigste zuerst, es ist nicht die Schuld von React, es ist nicht einmal die von Lerna, aber React, Webpack und npm-link müssen möglicherweise einige Verantwortung übernehmen.

Fallanforderung:

-Nicht-Monorepo:

  • haben symbolisch verknüpfte Pakete
  • Das symbolisch verknüpfte Paket hat die Komponente mithilfe von Hooks exportiert
  • Reagieren von clientseitigen Seiten

    • Wenn Sie an einem Monorepo arbeiten

  • Pakete symbolisiert
  • Pakete haben unterschiedliche Versionen von Abhängigkeiten (sogar Patch-Versionsunterschiede), sodass sogar Workspace gelöst wird, wenn 2 React installiert ist
  • Das Eingangspaket importierte ein symbolisch verknüpftes Paket, das Hooks verwendet

Beispiel

Struktur

- mono repo root
  - packages
    - ComponentWithHooks (peerDependency: react@^16.8.1)
    - ProductA (dependency: ComponentWithHooks, dependency: react@^16.8.4)
    - ProductB (dependency: react@^16.8.1)

Nach dem Bootstrap mit Arbeitsbereichen wird es aufgelöst

- mono repo root
  - node_modules
    - react(16.8.1)
  - packages
    - ComponentWithHooks
      - node_modules (empty)
    - ProductA
      - node_modules
        - react(16.8.4)
    - ProductB
      - node_modules (empty)

Und sobald Sie ProductA mit Webpack oder vielleicht etwas anderem bedienen, enthält es 2 Reaktionsinstanzen.

Code in ProductA, sucht nach ProductA/node_modules/react .

Aber das importierte ComponentWithHooks sucht nach mono repo root/node_modules/react .

Warum? Erinnern Sie sich an die Nachschlageregeln von npm? Wenn es das Modul nicht in seinem eigenen node_modules-Ordner finden kann, sucht es nach den node_modules des übergeordneten Elements ...

Also haben Tools wie Webpack diese Regel standardmäßig perfekt angewendet.
Es ist nichts falsch daran, dass die Mono-Repo-Lösung populär geworden ist.
Und normale Pakete werden dies nicht bemerken, da die meisten von ihnen keine einzelne Instanz als React und Redux benötigen.

Ich habe das gleiche Problem mit einer sehr einfachen Reproduktion unter Verwendung des Beispiels für Garnarbeitsbereiche - https://github.com/mwarger/yarn-workspace-hooks-repro

Ich habe ein component-library , das in Maschinenschrift geschrieben und mit einem Paket gebündelt ist. example-demo wird dieses component-library präsentieren und ist eine frisch erstellte CRA-App. Alle gängigen Pakete sind mit Garn gehisst, daher sollte es theoretisch nur eine Version von React geben. Der React.useEffect -Aufruf, den ich in index.tsx mache, verursacht jedoch den Fehler, der mich zu diesem GitHub-Problem führt.

Alles funktioniert, bis ein Haken hinzugefügt wird. Um den Fehler zu reproduzieren, kommentieren Sie die Zeilen 7-9 in component-library/src/index.tsx aus

Hoffentlich mache ich etwas Dummes, das ich übersehen habe. Bitte teilen Sie mir mit, mit welchen Schritten ich versuchen kann, dies zu beheben. Danke!

Folgebearbeitung: Die unten vorgeschlagene Ausgabe des Debug-Skripts gibt für mich true aus. Es scheint, dass ich keine zwei Reaktionen habe.

// Add this in node_modules/react-dom/index.js
window.React1 = require('react');

// Add this in your component file
require('react-dom');
window.React2 = require('react');
console.log(window.React1 === window.React2);

Ich habe mehrere Stunden gebraucht, also könnte es sich lohnen, hier eine Notiz zu machen.

In meinem Fall habe ich eine Zeile von <script defer src="./dist/bundle.js" /> in den Kopf der HTML-Vorlage eingefügt, die wie gewohnt funktioniert, wenn keine React-Hooks verwendet werden. Alle Lösungen funktionieren nicht und die window.React1 == window.React2 Prüfung gibt in diesem Fall true zurück.

Da das Webpack das Skript-Tag danach einfügt, sollte die Vorlage kein eigenes Skript-Tag haben. Entfernen Sie das Skript-Tag aus der Vorlage, machen Sie React wieder funktionsfähig mit Hooks (Wortspiel beabsichtigt).

In meinem Fall habe ich eine React-App, die npm mit einer Abhängigkeit verknüpft war, an der ich arbeitete. Dies reicht aus, bis ich ein paar Abhängigkeiten beheben kann, die react und react-dom in Dev- und Peer-Deps verschieben müssen.

  1. Aus der App: cd node_modules/react && npm link
  2. Aus der App: cd node_modules/react-dom && npm link react
  3. Aus dem verlinkten Paket: npm link react

Warum funktioniert es? Auf der Fehlerwarnseite wird erwähnt, dass „damit Hooks funktionieren, der React-Import aus Ihrem Anwendungscode in dasselbe Modul aufgelöst werden muss wie der React-Import aus dem React-Dom-Paket“.

Ich habe dieses Problem immer noch, obwohl ich alle oben genannten Punkte ausprobiert habe. Standard-Webpack4/Babel-Konfiguration mit preset-env - und preset-react -Plugins. Meine React/React-Dom-Versionen sind mithilfe von Garnauflösungen an 16.8.4 gepinnt (wobei auch die window.React1 === window.React2 -Prüfung von oben true zurückgibt).

Dies ist die grundlegendste Verwendung:

import React, { useState } from "react";

function MyComp() {
  const [hello] = useState(0);

  return <div>HELLO {hello}</div>;
}
export default MyComp;

Hat jemand noch andere Ideen?

BEARBEITEN: Zur Verdeutlichung wird der Fehler gemäß OP als react.development.js:88 Uncaught Invariant Violation: Hooks can only be called inside the body of a function component. angezeigt

In meinem Fall habe ich eine React-App, die npm mit einer Abhängigkeit verknüpft war, an der ich arbeitete. Dies reicht aus, bis ich ein paar Abhängigkeiten beheben kann, die react und react-dom in Dev- und Peer-Deps verschieben müssen.

  1. Aus der App: cd node_modules/react && npm link
  2. Aus der App: cd node_modules/react-dom && npm link react
  3. Aus dem verlinkten Paket: npm link react

Warum funktioniert es? Auf der Fehlerwarnseite wird erwähnt, dass „damit Hooks funktionieren, der React-Import aus Ihrem Anwendungscode in dasselbe Modul aufgelöst werden muss wie der React-Import aus dem React-Dom-Paket“.

Danke! Das funktioniert super für mich. (auch wenn ich eine gemischte Situation mit npm-Link und Symlink verwende)

Ich habe alles oben vorgeschlagene versucht und hatte immer noch den Fehler.

Mit ein wenig Hilfe von @inverherive fanden wir heraus, dass enzyme-adapter-react-16 immer noch Probleme verursachte.

Während wir react-test-renderer auf die neueste Version (16.8.4) aktualisiert haben, da es erst kürzlich Hooks-Unterstützung hinzugefügt hat, haben wir über npm ls react-test-renderer herausgefunden, dass die neueste Version von enzyme-adapter-react-16 (1.11.2 ) hatte eine interne Abhängigkeit von [email protected] , die keine Hooks unterstützt.

├─┬ [email protected]
│ └── [email protected] 
└── [email protected]

Um dieses Problem zu beheben und den Korrekturen von @chulanovskyi zu folgen, haben wir react-test-renderer Auflösungen zu unserer package.json hinzugefügt, da wir Garn verwenden. Dadurch werden alle Verweise auf react-test-renderer gezwungen, "16.8.4" zu verwenden.

  "resolutions": {
    "react-test-renderer": "16.8.4"
  },

Das war mega frustrierend, ich hoffe, das kann jemand anderem helfen. Danke auch an @chulanovskyi und @theKashey für ihre Vorschläge.

Dies wird ausreichen, bis ich ein paar Abhängigkeiten beheben kann, die React und React-Dom zu Dev- und Peer-Deps verschieben müssen.

@ajcrews (ich habe vielleicht etwas übersehen, aber) Ich habe npm link eine interne Bibliothek in und diese Bibliothek hat react in peerDependencies und devDependencies und ich brauchte immer noch deine fix trotzdem, um den Fehler zu beheben. Schöner Fund!

Ich wollte gerade posten, habe aber eine Lösung gefunden

Ich habe eine Komponentenbibliothek mit einer Beispiel-CRA-App für die Entwicklung

In der Datei „package.json“ der CRA-App musste ich „react“ und „react-dom“ ändern, um sie aus der „package.json“ der Root-Komponente zu „leihen“.

"dependencies": {
  "react": "link:../node_modules/react",
  "react-dom": "link:../node_modules/reac-dom",
}

Das war mega frustrierend, ich hoffe, das kann jemand anderem helfen. Danke auch an @chulanovskyi und @theKashey für ihre Vorschläge.

@Paddy-Hamilton Überprüfen Sie nach einer Installation immer Ihre Sperrdatei. Ich hatte das gleiche Problem, bei dem yarn react-test-renderer duplizierte. Mit ein wenig Eingriff in Ihre Sperrdatei könnten Sie diese beheben:

yarn add -D react-test-renderer

-react-test-renderer@^16.0.0-0, react-test-renderer@^16.1.1:
+react-test-renderer@^16.0.0-0:
  version "16.8.4"
  resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.8.4.tgz#abee4c2c3bf967a8892a7b37f77370c5570d5329"
  integrity sha512-jQ9Tf/ilIGSr55Cz23AZ/7H3ABEdo9oy2zF9nDHZyhLHDSLKuoILxw2ifpBfuuwQvj4LCoqdru9iZf7gwFH28A==
  dependencies:
    object-assign "^4.1.1"
    prop-types "^15.6.2"
    react-is "^16.8.4"
    scheduler "^0.13.4"

+react-test-renderer@^16.8.5:
+  version "16.8.5"
+  resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.8.5.tgz#4cba7a8aad73f7e8a0bc4379a0fe21632886a563"
+  integrity sha512-/pFpHYQH4f35OqOae/DgOCXJDxBqD3K3akVfDhLgR0qYHoHjnICI/XS9QDwIhbrOFHWL7okVW9kKMaHuKvt2ng==
+  dependencies:
+    object-assign "^4.1.1"
+    prop-types "^15.6.2"
+    react-is "^16.8.5"
+    scheduler "^0.13.5"

Ein yarn check würde dich schon warnen

$ yarn check
warning "enzyme-adapter-react-16#react-test-renderer@^16.0.0-0" could be deduped from "16.8.5" to "[email protected]"

deduplizieren Sie es dann manuell, indem Sie den folgenden Patch anwenden:

-react-test-renderer@^16.0.0-0:
-  version "16.8.4"
-  resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.8.4.tgz#abee4c2c3bf967a8892a7b37f77370c5570d5329"
-  integrity sha512-jQ9Tf/ilIGSr55Cz23AZ/7H3ABEdo9oy2zF9nDHZyhLHDSLKuoILxw2ifpBfuuwQvj4LCoqdru9iZf7gwFH28A==
-  dependencies:
-    object-assign "^4.1.1"
-    prop-types "^15.6.2"
-    react-is "^16.8.4"
-    scheduler "^0.13.4"
-
-react-test-renderer@^16.8.5:
+react-test-renderer@^16.0.0-0, react-test-renderer@^16.8.5:

Jetzt haben Sie eine einzige Version von react-test-renderer ohne resolutions oder webpack Alias-Spielereien.

Bei Problemen mit verknüpften Paketen und create-react-app folgen Sie facebook/create-react-app#6207

Es gibt viele Möglichkeiten, es zu lösen, und Garnauflösungen würden normalerweise nicht helfen - es hängt eher mit dem "Bauwerkzeug" zusammen.

  • Verwenden Sie für Webpack aliases - nur ein "harter" Alias, der alles wie react in eine einzelne Datei duckt
  resolve: {
    extensions: ['.ts', '.tsx', '.js', '.jsx'],
    alias: {
     react: path.resolve(path.join(__dirname, './node_modules/react')),
   }
import {setAliases} from 'require-control';
setAliases({
  'react': path.resolve(path.join(__dirname, './node_modules/react'))
});
  • Verwenden Sie zum Scherz moduleNameMapper
"jest": {
    "moduleNameMapper": {
      "^react$": "<rootDir>/node_modules/$1",
    },

Das hat es für mich getan.

@ajcrews
Danke! Funktioniert bei mir hervorragend!

Ich habe einen kleinen Testfall mit minimalem Setup mit React 16.8.6, Electron-Webpack und RHL erstellt. Insbesondere wenn dieser Fehler auftritt, beginnt der gesamte Browser (in diesem Setup Elektron) eine ganze Menge CPU-Zeit zu verbrauchen.

https://github.com/PerfectionCSGO/reeee

Ich zerbreche mir jetzt seit 3 ​​Tagen den Kopf über dieses Problem. Ursprünglich dachte ich, RHL sei das Problem, aber das vollständige Entfernen aus diesem Projekt wird das Problem nicht lösen.

npm ls reagieren gibt nur ein Ergebnis zurück. Ich habe sichergestellt, dass der obige Fix mit den neuesten Versionen + Webpack-Alias ​​angewendet wird.

Der Code funktioniert in einer Sandbox.

In einem einfachen Webpack/Website funktioniert der Code ohne Probleme. Bei Electron-Webpack besteht dieses Problem jedoch weiterhin.

  "dependencies": {
    "i18next": "^15.0.9",
    "i18next-browser-languagedetector": "^3.0.1",
    "react": "^16.8.6",
    "react-dom": "npm:@hot-loader/react-dom",
    "react-hot-loader": "^4.8.2",
    "react-i18next": "^10.6.1",
    "source-map-support": "^0.5.11",
    "tslint": "^5.15.0"
  },
  "devDependencies": {
    "@babel/core": "^7.4.3",
    "@babel/preset-react": "^7.0.0",
    "@babel/preset-typescript": "^7.3.3",
    "@types/react": "^16.8.12",
    "@types/react-dom": "^16.8.3",
    "electron": "^4.1.3",
    "electron-builder": "20.39.0",
    "electron-webpack": "^2.6.2",
    "electron-webpack-ts": "^3.1.1",
    "typescript": "^3.4.1",
    "webpack": "^4.29.6"
  }

Ich hoffe jemand kann mir einen Hinweis geben...

Wenn ich „react-l18next“ durch „mobx-react-lite“ ersetze und „beobachter“ verwende, wird derselbe Effekt erzielt.

In Bezug auf mein Problem habe ich es gelöst, indem ich das Elektron-Webpack gebeugt habe und mich für eine „reine“ Elektronenlösung entschieden habe. Ich vermute, dass es sich um eine in Webpack oder Babel verwendete Toolchain handelt, die nicht kompatibel ist.

Ich habe dieses Problem nur in der Produktion festgestellt. Keine der hier vorgeschlagenen Lösungen hat geholfen.
Mein Anwendungsfall war eine Drittanbieter-App, die als Widget auf einer anderen Website geladen wird.
Als die Seite zum ersten Mal mit dem Widget geladen wurde, funktionierte alles gut, aber wenn der Benutzer zu einer anderen Seite navigierte und zu der Seite mit dem Widget zurückkehrte, bekam ich den Hooks-Fehler.

Beachten Sie, dass der Fehler nur auftritt, wenn die Navigation kein Neuladen der Seite verursacht.

Ich verbrachte Stunden damit, herauszufinden, was das Problem war. Schließlich war das Problem mit dem Code-Snippet, das das App-Bundle lädt. Beim Seitenwechsel konnte das Bundle mehrmals geladen werden, was meiner Meinung nach zu mehreren React-Instanzen im selben Namensraum führte.

Ich habe es behoben, indem ich überprüft habe, ob das Skript bereits geladen wurde.
Zuerst habe ich meine Bibliothek in den globalen Namensraum exportiert, indem ich die Konfiguration „Bibliothek“ von Webpack verwendet habe:

output: {
    library: 'myLib',
    ...
}

Und dann habe ich im Ladeskript überprüft, ob die Bibliothek existiert oder nicht:

if(!window.myLib){
    var bz = document.createElement('script');
    bz.type = 'text/javascript'; 
    bz.async = true;
    bz.src = 'https://path/to/bundle.js';
    var s = document.getElementsByTagName('script')[0];
    s.parentNode.insertBefore(bz, s);
}

Es könnte ein sehr spezifischer Anwendungsfall sein, aber ich hoffe, dies kann jemand anderem helfen.

Wir haben also eine React-Hauptanwendung, die das Webpack nutzt.
Wir versuchen, eine kleine React-Bibliothek zu erstellen, die Hooks verwendet, wir haben versucht, Bundler auszutauschen (Parcel, Pure Babel, Webpack).
Beim Ausprobieren unserer Webpack-Implementierung haben wir „react“ und „react-dom“ als extern markiert, sodass wir sie nicht in unser Paket aufnehmen.
Wir erhalten immer noch die gleiche Hooks-Ausnahme, wenn wir npm link verwenden.

Das Erstellen eines Symlinks zur Reaktion der Hauptanwendung funktioniert, aber es ist kein großartiger Entwicklungsworkflow.

Ich habe Schwierigkeiten, die zugrunde liegende Ursache des Problems herauszufinden. Was erzeugt eine doppelte React-Instanz?

Hallo @adriene-orange , vielleicht findest du meinen Beitrag https://github.com/facebook/react/issues/13991#issuecomment -472740798 für weitere Erklärungen.

Die durch den npm-Link verursachte Mehrfachinstanz liegt daran, dass der Knoten standardmäßig in den node_modules des übergeordneten Ordners nach dem Modul sucht, wenn es in Ihrem Paket nicht gefunden werden kann.

Die einfachste und beste Lösung, die wir dafür finden, ist die Webpack-Konfiguration (oder andere Tools) Ihres Einstiegspakets. Dort gibt es so etwas wie resolve.modules , um die Pfade manuell festzulegen und die Pfade zu ordnen, in denen das Webpack nach Modulen sucht. Exp., resolve: { modules: [path.resolve(PACKAGE_ROOT, 'node_modules'), 'node_modules'] } , zwingt Webpack, zuerst Module im node_module Ihres Einstiegspaket-Stammverzeichnisses zu finden. Wenn Sie das Modul nicht im Stammverzeichnis finden können, suchen Sie es im relativen Ordner node_modules ...

Wir haben also eine React-Hauptanwendung, die das Webpack nutzt.
Wir versuchen, eine kleine React-Bibliothek zu erstellen, die Hooks verwendet, wir haben versucht, Bundler auszutauschen (Parcel, Pure Babel, Webpack).
Beim Ausprobieren unserer Webpack-Implementierung haben wir „react“ und „react-dom“ als extern markiert, sodass wir sie nicht in unser Paket aufnehmen.
Wir erhalten immer noch die gleiche Hooks-Ausnahme, wenn wir npm link verwenden.

Das Erstellen eines Symlinks zur Reaktion der Hauptanwendung funktioniert, aber es ist kein großartiger Entwicklungsworkflow.

Ich habe Schwierigkeiten, die zugrunde liegende Ursache des Problems herauszufinden. Was erzeugt eine doppelte React-Instanz?

Hallo, ich bekomme diesen Fehler

Invarianten Verstoß: Ungültiger Hook-Call. Hooks können nur innerhalb des Körpers einer Funktionskomponente aufgerufen werden. Dies kann aus einem der folgenden Gründe geschehen:
1. Möglicherweise haben Sie nicht übereinstimmende Versionen von React und dem Renderer (z. B. React DOM)
2. Sie könnten die Hook-Regeln brechen
3. Möglicherweise haben Sie mehr als eine Kopie von React in derselben App
Unter https://fb.me/react-invalid-hook-call finden Sie Tipps zum Debuggen und Beheben dieses Problems.

   5 | 
   6 | const useApiHelper = (url, reducer) => {
>  7 |     const [state, dispatch] = useReducer(reducer, {});
     |                                                  ^
   8 | 
   9 |     useEffect(() => {
  10 |         fetch(url).then(res => res.json())

Beispielcode https://stackblitz.com/edit/react-mbze9q

Wenn ich versuche, auf diese Funktion in Testfällen zuzugreifen, erhalte ich den obigen Fehler

@abhishekguru Sie rufen den Hook hier in Ihrem Test außerhalb einer Komponente auf:

test('API test', async () => {
  const newState = useAPIHelper( // <- Called outside of a component
    'https://jsonplaceholder.typicode.com/posts',
    reducer
  )
  console.log(newState, 'new');
  // expect(newState[samUrl].loading).toEqual(true);
});

Wie der Fehler besagt, können Hooks nur von einem anderen Hook oder innerhalb einer Komponente aufgerufen werden. In Ihrem Fall könnten Sie eine Komponente für Ihren Test erstellen und diese Komponente rendern, die den Hook verwendet, wenn Sie möchten.

Schamloser Stecker

@abhishekguru Wenn Sie einen generischen Hook haben, der zwischen mehreren Komponenten verwendet wird, und Sie ihn unabhängig von einer bestimmten Komponente testen möchten, sollten Sie die Verwendung react-hooks-testing-library in Betracht ziehen.

import { renderHook } from 'react-hooks-testing-library'

test('API test', async () => {
  const { result } = renderHook(() => useAPIHelper( // <- now called within a component
    'https://jsonplaceholder.typicode.com/posts',
    reducer
  ))

  console.log(result.current, 'new');
  // expect(result.current[samUrl].loading).toEqual(true);
});

Ich wollte mich hier einmischen, weil wir nur Probleme mit SSR hatten. Wir löschen den Knoten require.cache bei Dateiänderungen. Dies führt effektiv zu einem heißen Neuladen auf dem Server. Das Löschen von require.cache des Knotens führt zu Problemen mit Bibliotheken, die eine einzige Kopie benötigen. Hier ist unsere Lösung:

Object.keys(require.cache)
  .filter(key => !isSingleton(key)) // This is needed here because react cannot be deleted without causing errors
  .forEach(key => {
    delete require.cache[key]
  })

Unsere Funktion isSingleton enthält die Liste der Bibliotheken, die eine einzige Kopie haben müssen. Eine gute Faustregel ist jede Bibliothek, die in peerDependencies definiert werden muss

https://yarnpkg.com/lang/en/docs/dependency-types/#toc -peerdependencies

Hatte auch das gleiche Problem und bei mir

window.React1 = require('react');
require('react-dom');
window.React2 = require('react');
console.log(window.React1 === window.React2); // true

gab auch true zurück, versuchte alle gegebenen Vorschläge, aber nichts funktionierte. Schließlich stellte sich heraus:

Webpack fügt das Skript-Tag mit dem bundle.js index.html ein. Mein Problem war, dass ich bundle.js index.html hinzufügte , was vor Hooks gut funktionierte.

Für mich war das Problem nach dem Upgrade von Babel 7, es gab keine separaten Versionen mit npm ls reagieren. Entfernen
"react-hot-loader/babel" von .babelrc hat das Problem vorübergehend behoben.

Ich habe alle oben genannten Lösungen ausprobiert, aber immer noch den Fehler.
Schließlich fand ich heraus, dass es durch das Paket why-did-you-update verursacht wurde, und es gibt ein damit zusammenhängendes Problem . Nur ein Hinweis für alle, die ein ähnliches Paket verwenden, das React modifiziert.

Ich konnte dies in einem react-native + Yarn Workspaces Szenario beheben.


Im Stammverzeichnis package.json

{
  "private": true,
  "workspaces": {
    "packages": [
      "packages/*"
    ],
    "nohoist": [
      "**/react-native",
      "**/react-native/!(react)/**"
    ]
  }
}

Dies verhindert, dass react-native -Code gehisst wird (wie es für React Native erforderlich ist), während react immer noch gehisst wird, sodass alle gemeinsam genutzten Module dasselbe React verwenden.


Im metro.config.js

module.exports = {
  watchFolders: [
    path.resolve(__dirname, '../', 'shared-module'), 
    // ...more modules
    path.resolve(__dirname, '../', '../') // to make sure the root `react` is also part of the haste module map
  ]
}

Die Metro-Konfiguration lässt den Bundler wissen, wo sich alles befindet.

Ich habe einen Weg gefunden, das Problem für Leute zu lösen, die beispielsweise lokal ein npm-Paket entwickeln und versuchen, es lokal zu testen, indem sie ihr Paket über den npm-Link in eine Art Beispiel-App laden.

Ich bin von der Beispiel-App (ursprüngliche Methode zum Testen der Komponente) zu Storybook gewechselt. Wenn Sie das Storybook im Projekt verwenden, wird React nicht zweimal geladen, da es dasselbe verwendet, das auch die Komponente verwendet. Bei der Verwendung von npm link hatte ich Probleme mit Hooks und React, die zweimal geladen wurden, außerdem konnte ich keine der oben genannten Lösungen zum Laufen bringen. Also hat Storybook mein Problem gelöst, und jetzt habe ich eine Möglichkeit, meine Komponente in mehreren Szenarien zu testen und gleichzeitig eine interaktive Dokumentation dafür zu erstellen.

Ich teilte meine Erfahrung damit und löste es für unser Projekt, indem wir Webpack-Externals für die Komponentenbibliothek verwendeten, um react und react-dom aus dem Build auszuschließen.

Wir fangen gerade erst mit React an. In meinem Fall beginnen wir mit Lerna monorepo mit Neutrino-Komponentenbibliothekspaket und Neutrino-Webapp-Clientpaket. Die Webanwendung verwendet das Build-Produkt der verknüpften Komponentenbibliothek. Nach einigem Experimentieren und Erhalten true für dieselbe React-Instanz habe ich nach einer Möglichkeit gesucht, react und react-dom überhaupt aus dem Build der Komponentenbibliothek auszuschließen.

Es scheint eine gängige Entwurfsmusterlösung für Webpack -Komponentenbibliotheken zu sein, also habe ich in der Komponentenbibliothek die Webpack-Konfiguration hinzugefügt:

"externals": {
  "react": "react",
  "react-dom": "react-dom"
}

Ich musste kein globales Skript-Tag in das webapp-Paket für react und react-dom einfügen. Ich vermute, Webpack stellt diese der Komponentenbibliothek in seiner require -Implementierung genauso zur Verfügung wie der Webapp.

Eine weitere Ursache für diesen Fehler ist die falsche Konfiguration von Route des React Routers.

Das schlägt fehl :

<Route render={MyHookedComponent}/>

, aber das gelingt :

<Route component={MyHookedComponent}/>

Z.B. Sie müssen component verwenden, nicht render . Dies ist ein leichter Fehler, da render im Allgemeinen gut mit klassenbasierten Komponenten funktioniert.

Ich habe an Invalid Hook call warning gearbeitet und möchte es auf npm veröffentlichen und mit Hilfe von npm link entwickeln.
Ich habe versucht, npm link ../myapp/node_modules/react zu verwenden, aber es löst mein Problem nicht,
Und verglichen mit React1 === React2 ist es wahr sowie npm ls react auch getan, es zeigt nur ein Paket.

Und ich verwende auch kein Webpack, ich füge nur eine Ebene außerhalb von create-react-app hinzu, damit ich meine App nicht dazu zwingen kann, das lokal installierte React-Modul zu verwenden.
Ich stecke seit 3 ​​Tagen damit fest._

Das gleiche wie @hnagarkoti .

Ich habe diese Warnung während des serverseitigen Renderns (SSR) erlebt, weil ich eine ältere Version von react-apollo verwendet habe, also wollte ich diesen Link hier hinterlassen, um der nächsten armen Seele zu helfen, die auf dieses Problem stößt:

https://github.com/apollographql/react-apollo/issues/2541

Kurz gesagt, getDataFromTree unterstützt bis zur Version [email protected] keine Reaktionshaken.

Ich hatte das gleiche Problem und habe es gelöst, indem ich hinzugefügt habe:

 alias: {
        react: path.resolve('./node_modules/react')
      }

in die Eigenschaft resolve in der Webpack-Konfiguration meiner Haupt-App.

Es war offensichtlich mein Fehler, zwei Kopien von React zu verwenden, aber ich stimme zu, dass es großartig wäre, wenn die Fehlermeldung besser wäre. Ich denke, das ist vielleicht ähnlich wie: #2402

Irgendwelche Vorschläge, dies mit create-react-app zu tun?

^ Ok, die Lösung, die ich gewählt habe, um dies für create-react-app zu lösen, ist die Verwendung von „react-app-rewired“ und „ customize-cra“.

Hier ist meine config-overrides.js :

const {
    override,
    addWebpackAlias,
  } = require("customize-cra");

const path = require('path'); 

module.exports = override( 
    addWebpackAlias({
        react: path.resolve('./node_modules/react')
    })
)

Beispielprojekt: https://github.com/dwjohnston/material-ui-hooks-issue/tree/master

In unserem Team haben wir eine universelle Navigationskomponente, die über Dutzende von Apps hinweg funktioniert. Alle diese Apps stammen von React 15.0.0 bis React 16.8.0. Um die über Hooks implementierte Navigation zu ermöglichen, müssen wir sie mit einem neuesten React bündeln

In diesem Fall ist es eine grundlegende Voraussetzung für uns, mehrere Instanzen von React zu haben. Ich würde gerne wissen, ob das offizielle Team von React bereit ist, dieses Problem in Zukunft zu lösen?

@dwjohnston meine Problemumgehung für create-react-app bestand darin, eine Webpack-Konfiguration für die Entwicklung zu erstellen. create-react-app verwendet intern Webpack, Webpack-dev-server und den babel-loader, also war das Erstellen einer Webpack-Konfiguration nur für die Entwicklung nicht so schlimm, da die Abhängigkeiten bereits implizit vorhanden sind, aber immer noch eine Menge Overhead zu bekommen ist das funktioniert richtig.

Ich habe ein Problem mit create-react-app : https://github.com/facebook/create-react-app/issues/6953 zum Hinzufügen von Unterstützung für Webpack alias oder ähnliches.

👋 Wenn jemand auch create-react-app verwendet und diesen Schmerzpunkt hat, könnten Sie diesem Problem bitte einen Daumen nach oben geben?

@ricokahler - Danke, dass du darauf hingewiesen hast. Ich bin froh zu sehen, dass ich nicht die einzige Person mit diesem Problem bin - ich bin auch im Kontext darauf gestoßen.

Gibt es Quellen, die Sie kennen, die dieses Problem weiter diskutieren?

Wenn Sie in meinem Boot sind, haben Sie ein React-Komponentenpaket aus einem lokalen Verzeichnis hinzugefügt, und jetzt wird es automatisch erstellt und installiert, zusammen mit seiner eigenen Kopie von node_modules (da es dafür npm-Link verwendet), und geben Sie Ihre App 2 Kopien oder Jetzt reagieren.

Ich habe es umgangen, indem ich die node_modules/ gelöscht habe./node_modules vor dem Ausführen der App. Um dies automatisch zu tun:

"prestart": "rimraf ./node_modules/<my_package>/node_modules"

Das habe ich auch bei SSR erlebt.
Wenn Sie Lerna zum lokalen Testen Ihrer React-Bibliothek verwenden, können Sie „react/react-dom/react-router“ als peerDependencies zu Ihrer Bibliothek hinzufügen, aber Sie sollten sie nicht als devDependencies hinzufügen. (dadurch wird es dupliziert)
Sie können node --preserve-symlinks verwenden, damit es nach dem übergeordneten Repo suchen kann, das die peerDependencies installiert.
Für Jest müssen Sie den übergeordneten Repo-Pfad zur Option „jest.moduleDirectories“ hinzufügen, damit Jest sie auflösen kann

@apieceofbart es funktioniert bei mir, danke!

Ich bin auf diesen Fehler gestoßen, als ich externe React-Komponenten geladen habe, zum Beispiel mit JS-Modulen. Sie befinden sich vollständig außerhalb des Projekts und werden mit dynamischem Import () geladen (auch jsonp für mehr Unterstützung). Um das Problem zu umgehen, übergeben/injizieren wir React als Eigenschaft an jedes Modul. Das funktioniert, aber dann ist jedes Modul von der enthaltenen React-App abhängig. Wir versuchen, Abhängigkeiten zu entfernen.

Wie andere bereits erwähnt haben, eliminiert diese Eigenschaft React als verwendbar für jede Art von Mikro-Frontend. Das Problem ist, dass es diesen Nebeneffekt beim Erstellen eines globalen Status in der JS-Laufzeit gibt, wenn React importiert wird, um es als Bibliothek zu verwenden.

Ich verstehe, dass für einfache Anwendungsfälle dieser Nebeneffekt bedeutet, dass React "einfacher zu verwenden" ist. Aber wenn eine Webseite aus mehreren Skripten aus mehreren Bundle-Schritten besteht, sollte einer von ihnen in der Lage sein, React einzurichten (diesen Nebeneffekt explizit auszuführen), und die anderen können einfach Bibliotheksfunktionen aufrufen.

Ich habe immer noch ein Problem mit React-Bootstrap: # https://github.com/react-bootstrap/react-bootstrap/issues/3965

Für alle anderen, die beim Versuch, eine Bibliothek für React zu erstellen, nicht weiterkommen, versuchen Sie es mit https://github.com/whitecolor/yalc , es funktioniert viel besser als Symlinks.

@mpeyper funktioniert gut. Vielen Dank

@apieceofbart Das hat bei mir funktioniert. Danke für den Vorschlag. 👍

Bei mir wurde dieses Problem verursacht, als ich in PowerShell zu meinem Projektverzeichnis navigierte und keinen Verzeichnisnamen im Pfad großgeschrieben habe. Ich habe das Projekt in Benutzer/…/… anstelle von Benutzer/…/… erstellt.
Das Problem wurde behoben, als ich Großschreibungsfehler behoben und das Projekt neu erstellt habe.

Für mich tun:

    "react": "file:../my-library/node_modules/react",
    "react-dom": "file:../my-library/node_modules/react-dom",

Das meiste davon wurde behoben, aber es war nicht genug, ich bekam immer wieder den Fehler hooks can only be called inside the body of a function component .

Es stellte sich heraus, dass einige der Komponenten meiner Bibliothek so exportiert wurden:

export default Radium(withTranslation()(MyComponent))

:x:

Wobei withTranslation die HOC von „react-i18next“ und Radium die HOC von Radium ist.

Und sie so exportieren:

export default withTranslation()(Radium(MyComponent))

:heavy_check_mark:
Alles repariert.

Beachten Sie, dass „react-i18next“ in Version 10 war, die React Hooks verwendet

@mikeaustin Wir haben das gleiche Problem. Haben Sie ein Beispiel für das "Übergeben/Injizieren von React als Eigenschaft für jedes Modul"?

Immer noch dieses Problem, alle Schritte ausprobiert:

  • Garnarbeitsplätze (via lerna)
  • überprüft, ob es eine Reaktionsdep gibt, ja

Einige Dinge, die Auswirkungen haben können:

  • Verwendung von webpack mit libraryTarget
  • mit Typoskript
$ npm ls react-dom
/xxx
└── [email protected]

$ npm ls react
/xxx
└── [email protected]

Root-Paket.json

{
  ...
  "workspaces": [
    "packages/*",
  ],
  "devDependencies": {
    ...
  },
  "dependencies": {
    "react": "16.8.6",
    "react-dom": "16.8.6"
  },
  "resolutions": {
    "react": "16.8.6",
    "react-dom": "16.8.6",
    "**/react": "16.8.6",
    "**/react-dom": "16.8.6"
  }
}

@JeremyGrieshop Ich hatte das gleiche Problem und das hat bei mir funktioniert, danke.

Fügen Sie "prestart" in Ihrer package.json wie folgt hinzu:

"scripts": {
    "prestart": "rimraf ./node_modules/<my package>/node_modules",
    "start": "react-scripts start",
    "build": "react-scripts build",
  },

Ich hatte dieses Problem und es lag nicht an mehreren Versionen von React / React-Dom
In den von mir verwendeten benutzerdefinierten Tools wurde der erforderliche Cache gelöscht (für einen Zweck außerhalb dieser Diskussion), z.

Object.keys(require.cache).forEach((key) => {
      delete require.cache[key];
    });

Also zu Ihrer Information an die Leute da draußen, wenn Sie so etwas tun - es wirkt sich auf React Hooks aus, also vermeiden Sie es, wenn Sie können

Ich hatte das gleiche Problem und habe es gelöst, indem ich hinzugefügt habe:

 alias: {
        react: path.resolve('./node_modules/react')
      }

in die Eigenschaft resolve in der Webpack-Konfiguration meiner Haupt-App.

Es war offensichtlich mein Fehler, zwei Kopien von React zu verwenden, aber ich stimme zu, dass es großartig wäre, wenn die Fehlermeldung besser wäre. Ich denke, das ist vielleicht ähnlich wie: #2402

Für alle da draußen, die Parcel verwenden, sollten Sie Folgendes hinzufügen, wenn dist dort ist, wo sich Ihre kompilierten Dateien befinden:

  "alias": {
    "react-mediator": "./dist"
  },

Zu Ihren package.json und dann können Sie immer noch link (npm oder Garn) die Bibliothek für lokale Entwicklung/Tests verwenden.

@mikeaustin Wir haben das gleiche Problem. Haben Sie ein Beispiel für das "Übergeben/Injizieren von React als Eigenschaft für jedes Modul"?

Sie können React Context verwenden, um „React“ selbst weiterzugeben, und ein HoC erstellen, um die Eigenschaft in jede Komponente einzufügen. Sie können alles in api wie api.React übergeben, aber es wird ein wenig schwierig, HoCs um diese Komponenten zu wickeln (da sie jetzt nur innerhalb einer Komponente verfügbar sind und nicht exportiert werden können.

const withReact = Component = props => (
  <ReactContext.Provider value={api => <Component api={api} {...props} /> } />
)

Ich verbringe ein paar Stunden damit, wenn das Ändern des Quellcodes zum Ändern der Fehlermeldung und das Hinzufügen weiterer Informationen nicht einfach ist und Sie mehr Zeit benötigen, fügen Sie zumindest diese Notiz in das Dokument ein.

_p.s: „react“ hat eine großartige Dokumentation, aber ich denke, diese Seite muss überprüft werden._

@OliverRadini

Ich konnte dies beheben, indem ich react-hot-loader auf ^4.6.0 aktualisierte

Maaan, das hat es behoben.
@gaearon @theKashey Wie wäre es, wenn Sie dies zu https://reactjs.org/warnings/invalid-hook-call-warning.html hinzufügen, damit die Leute ihre Zeit nicht wegen einer älteren Version von react-hot-loader verschwenden?

Ich dachte, es ist schon ziemlich gut dokumentiert in einem Dutzend Ausgaben.

Hallo, ich verwende React sowohl in einer App als auch in einer Bibliothek . Ich benutze die Bibliothek in der App. Ich habe es geschafft, das Problem mit den zwei Reaktionsinstanzen zu beheben, indem ich Folgendes verwendet habe:

In der App -Webpack-Konfiguration:

    alias: { react: path.resolve( '__dirname', '..',  'node_modules', 'react' ) // Adapt this to match your file tree

In der Bibliothek webpack config

  externals: {
    react: 'react', // Case matters here
    'react-dom': 'react-dom' // Case matters here
  }

Ich habe also ein Problem mit dem Aufrufen von Hooks aus einer nicht transpilierten Datei (*.js):

index.js :

import ReactDOM from 'react-dom';
import './index.css';
import App from './app';

ReactDOM.render(App(), document.getElementById('root'));

app.jsx

import React from 'react';
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';
const BaseContext = React.createContext();

const initialState = {
  woo: true
};

const reducer = (state, action) => {
  switch (action.type) {
    default:
      return state;
  }
};

const Home = () => <h1>You're at home.</h1>;

const App = () => {
  // eslint-disable-next-line
  const [state, dispatch] = React.useReducer(reducer, initialState);
  return (
    <Router>
      <BaseContext.Provider value={initialState}>
        <BaseContext.Consumer>
          <div className="welcome">
            <nav>
              <ul>
                <li>
                  <Link to="/">Home</Link>
                </li>
              </ul>
            </nav>
            <header className="header">
              <h1>Welcome!</h1>
            </header>
            <Route path="/" exact component={Home} />
          </div>
        </BaseContext.Consumer>
      </BaseContext.Provider>
    </Router>
  );
};
export default App;

Irgendwelche Ratschläge, vorausgesetzt, es ist nicht "In JSX-Datei verschieben und transpilieren"?

Nichts scheint für mich zu funktionieren, ich verwende eine Mischung aus Stimulus und Reaktion, ich habe eine Hybrid-App, fing an, Hooks zu verwenden, und es schlug fehl, sobald ich anfing, Turbolinks hinzuzufügen :(

Bearbeiten: Im Moment habe ich mein Problem gelöst, indem ich data-turbolinks-track="reload" data-turbolinks-eval="false" zu den Skript-Tags hinzugefügt habe, die ich verwende, damit das jetzt funktionieren sollte

Ich habe die gleiche Frage, nach 4 Stunden wurde mir klar, dass jenkins util fehlt, um .babelrc-Dateien auf den Server umzuwandeln。。。

Warum würde dies den Fehler erzeugen?

$ npm ls react
[email protected] /mnt/g/development/javascript/pow-vehmain
└── [email protected]`
Invalid hook call...
ServiceVisitMaintenance
src/components/ServiceVisit/ServiceVisitMaintenance.js:6
  3 | import { ServiceVisitForm } from './ServiceVisitForm';
  4 | 
  5 | const data = [{ id: 1, description: 'Ford' }, { id: 10, description: 'Edsel' }];
> 6 | const ServiceVisitMaintenance = () => {
  7 |   const [vehicleList, setVehicleList] = useState([]);
  8 |   return (
  9 |     <div>

ServiceVisitMaintenance.js:

import React, { useState } from 'react';
import { ServiceVisitForm } from './ServiceVisitForm';
const data = [{ id: 1, description: 'Ford' }, { id: 10, description: 'Edsel' }];
const ServiceVisitMaintenance = () => {
  const [vehicleList, setVehicleList] = useState([]);
  return (
    <div>
      <ServiceVisitForm vehicleList={data} />
    </div>
  );
};

export { ServiceVisitMaintenance };

Bitte überprüfen Sie, was Ihre React-Dom-Version ist.

$ npm ls React-Dom
[email protected] /mnt/g/development/javascript/pow-vehmain
└── [email protected]

Ich war damit konfrontiert, als ich eine Verbindung (mapStateToProps) (MyComponent) aus der Bibliothek exportierte und diese Bibliothek in meiner CRA-App verwendete.

Nein, das war mein schlimmer Fehler. Die Routine, die dies aufgerufen hat, hat den React-Router-Dom verwendet und die Render-Prop anstelle der Komponente verwendet.

Hatte jemand von euch das gleiche Problem, aber mit Gatsby?

Ich bekomme das folgende Ergebnis, nachdem ich 'npm ls reagieren':
image

und 'npm ls reagieren-dom'
image

Zuerst dachte ich, ich hätte React versehentlich global installiert, nach der globalen Deinstallation änderte sich nichts. Dann habe ich versucht, ein völlig neues Projekt in einem anderen Verzeichnis zu erstellen, „gatsby new random-name“, und eine winzige Funktion hinzugefügt (Kommentare hinzufügen, gefolgt von https://www.youtube.com/watch?v=asrdFuAxPaU&feature=youtu .be) an die gatsby-starter-default um zu testen ob sich der Fehler selbst reproduzieren würde. Nun, zu meinem Leidwesen tat es das!

Jeder Rat würde von einem frustrierten Plebe gut aufgenommen werden.

Ich stehe immer noch vor diesem Problem in Storybook. Ist diese Ausgabe von npm ls korrekt oder nicht?
imageimage

In meinem Fall wurde das Problem durch das Modul why-did-you-update verursacht.

Verwenden Sie entweder workspace und lerna monorepo und ziehen Sie das Paket hoch. das wird problem lösen.

Wir haben das gleiche Problem mit SSR. Es scheint zu funktionieren, indem Sie externals: [“react”] in unserer Webpack-Konfiguration festlegen und dann react/umd/react.development.js manuell laden. Dies ist jedoch ein Schmerz und würde gerne einen einfacheren Weg finden.

Ok, hoffentlich hilft das jemandem. Wir haben das webpack runtime.js versehentlich mehrmals geladen, was dazu führte, dass mehrere Kopien von React existierten. Stellen Sie sicher, dass Sie den runtimeChunk (runtime.js) nur einmal laden.

Wenn Sie das Problem mit Ihren Jest-Tests wie ich haben, scheint dies das Problem für mich zu beheben.
Fügen Sie dies in Ihrem jest.config.js

moduleNameMapper: {
    '^react$': '<rootDir>/node_modules/react/'
  }

Es wäre schön, wenn dieser Fehler zumindest auf die Datei verweisen würde, in der er auftritt. Ich habe versehentlich einen Hook in einer normalen Funktion aufgerufen und es war schwer zu debuggen.

Ich habe eine andere Ursache für das Problem und eine Lösung dafür gefunden.

Meine Umgebung ist electron und webpack , aber das könnte auch Nicht-Elektronen-Leuten helfen. Ich habe schmerzhafte Tage damit verbracht, herauszufinden, warum ich diese Fehlermeldung nach dem Upgrade auf React 16.9 (und React DOM 16.9) erhalte.

In meinem Fall schien ich zwei Reacts in der App zu haben, aber ich konnte keine zwei physischen Bibliotheken in node_modules finden, nicht einmal mit npm ls react . Ich habe sogar webpack-bundle-analyzer verwendet, um zu sehen, was in dem Bündel drin ist.

Irgendwann stellte ich fest, dass ich physisch keine zwei Reaktionen im Projekt habe, aber React und React DOM wurde zweimal in der HTML-Datei referenziert/geladen . Dies kann leicht überprüft werden, indem man zB console.log("React load") zur index.js der React-Bibliothek hinzufügt.

Die wirkliche Quelle war mit electron-webpack verbunden. „ react“ und „react-dom“ wurden nicht als extern markiert und wurden daher sowohl im Bundle als auch später von „node_modules“ geladen, da sie in einem anderen Modul verwendet werden müssen.

Die Lösung war so einfach wie das Hinzufügen dieser Zeilen zu webpack.renderer.config.js :

module.exports = {
    externals: [
        "react",
        "react-dom"
    ],
};

Okay, wenn hier also jemand packet.js verwendet, konnte ich aus irgendeinem seltsamen Grund mit dem folgenden Import davonkommen: import React from 'React'; und als ich anfing, React-Hooks zu verwenden, bekam ich den unveränderlichen Verletzungsfehler, der nicht merkte, dass es so war weil ich fälschlicherweise mit from 'React' anstelle von from 'react' importiert habe. Hoppla.

Hatte jemand von euch das gleiche Problem, aber mit Gatsby?

Ich bekomme das folgende Ergebnis, nachdem ich 'npm ls reagieren':
image

und 'npm ls reagieren-dom'
image

Zuerst dachte ich, ich hätte React versehentlich global installiert, nach der globalen Deinstallation änderte sich nichts. Dann habe ich versucht, ein völlig neues Projekt in einem anderen Verzeichnis zu erstellen, „gatsby new random-name“, und eine winzige Funktion hinzugefügt (Kommentare hinzufügen, gefolgt von https://www.youtube.com/watch?v=asrdFuAxPaU&feature=youtu .be) an die gatsby-starter-default um zu testen ob sich der Fehler selbst reproduzieren würde. Nun, zu meinem Leidwesen tat es das!

Jeder Rat würde von einem frustrierten Plebe gut aufgenommen werden.

Ja, ich bin auf das gleiche Problem gestoßen wie Sie. Ich habe den Rat hier befolgt ... ,

// Add this in node_modules/react-dom/index.js
window.React1 = require('react');

// Add this in your component file
require('react-dom');
window.React2 = require('react');
console.log(window.React1 === window.React2);

Ich habe React2 zur Indexdatei unter Seiten hinzugefügt. Es gibt falsch zurück.

Dedupliziert bedeutet, dass npm die Abhängigkeit hätte deduplizieren sollen, siehe hier ...

Dasselbe Paket muss nicht zweimal installiert werden! Es wird nur referenziert.

Außerdem bewegt es die Pakete "den Baum hinauf" (flacht den Baum ab). Dies ist absolut sinnvoll, da sonst ein Paket in den node_modules eines anderen Pakets suchen müsste (was ziemlich chaotisch wäre) und hilft, die Abhängigkeiten zu vereinfachen.

Sie können dies überprüfen, da jedes Paket in Ihrem Abhängigkeitsdiagramm, das dedupliziert anzeigt, mindestens ein weiteres Mal im Diagramm gefunden werden kann, normalerweise auf einer „höheren Ebene“.

Obwohl das Deduplizieren offensichtlich nicht funktioniert hat.

Was hast du versucht?

Ich erhalte diesen Fehler, wenn ich versuche, mit NextJS zu bauen. Einige Komponenten verwenden Material-UI und das Problem verschwindet, wenn ich sie entferne. Ich verwende keine Stilkomponenten. Ich habe versucht, node_modules usw. ohne Glück zu löschen. Ich habe versucht, Aliase und Auflösungen für react in meiner Datei next.config.js und package.json hinzuzufügen, ohne Erfolg. Ich verwende React 16.8.6, React-Dom 16.8.6 und Next 9.0.4. npm ls sagt, dass es jeweils nur einen gibt. Ich verwende keine npm-Links.

Repository: https://github.com/dancancro/questions/tree/invalid-hook-call

Codesandbox ist hier: https://codesandbox.io/s/github/dancancro/questions/tree/invalid-hook-call/?fontsize=14

Stackoverflow: https://stackoverflow.com/questions/57647040/nextjs-invalid-hook-call-hooks-can-only-be-called-inside-of-the-body-of-a-fun

Der Fehler ist hier: https://gist.github.com/dancancro/2dfafb053aaaedfade406fd4f67eb68a
... render -> renderToString -> ReactDOMServerRenderer.read -> ReactDOMServerRenderer.render -> Object.WithStyles [als render] ...

Der problematische Hook ist ein useStyles() -Aufruf in Zeile 17428 der folgenden Datei in einer withStyles -Funktion. Suchen Sie nach „var class = useStyles(props)“. Das Problem ist mit nextjs-generiertem Code. Der Code, den ich geschrieben habe, verwendet weder withStyles noch Hooks oder Funktionen, die mit „use*“ beginnen.

https://raw.githubusercontent.com/dancancro/questions/invalid-hook-call/.next/static/development/pages/index.js

UPDATE: Das Entfernen aus meiner next.config.js löste das Problem:

    webpack: config => {
        config.externals = [
            '/'
        ]
        return config
    },

Ich habe eine Problemumgehung entdeckt, indem ich react und react-dom aus dem Ordner node_modules meines verknüpften Pakets gelöscht habe.

Ich bin im selben Boot wie viele von Ihnen. Ich habe ein Bibliothekspaket, an dem ich lokal arbeite, und ich möchte mir nicht die Mühe machen, es jedes Mal zu veröffentlichen, wenn ich Änderungen in meinem Anwendungspaket sehen muss. Ich habe es verlinkt und bekam diesen Fehler.

Hier ist die Problemumgehung:

  • Paket A: Ihr Bibliothekscodepaket wurde npm link 'd
  • Paket B: Ihr Anwendungscodepaket. Enthält einen symbolischen Link in Ihrem node_modules -Ordner für Paket A
  1. Erstellen Sie Paket A. Mine gibt seine Assets an dist/ aus, einschließlich seiner node_modules
  2. Löschen Sie im verteilten Ordner node_modules Paket A react und react-dom
  3. ???
  4. Profitieren!

Beachten Sie, dass ich in beiden Paketen dieselbe Version von React installiert hatte. Sie müssen alle laufenden Prozesse neu starten.

Inkompatibles why-did-you-update entfernen funktioniert bei mir. (https://github.com/maicki/why-did-you-update/issues/52)

inkompatibel warum-haben-sie-aktualisiert

@bertho-zero use kann die neuen devtools oder meinen Hook useWhyDidYouUpdate verwenden

@brunolemos Es ist großartig, aber einschränkender, weil Sie es auf jede Komponente setzen müssen.

Die Lösung von @ dmart914 hat das Problem für mich gelöst. Ich habe auch Pakete verlinkt, damit ich meine Bibliothek testen kann, ohne eine Änderung zu veröffentlichen ... hat jemand eine Problemumgehung dafür gefunden? Es ist keine großartige Erfahrung, eine Open-Source-Bibliothek zu veröffentlichen und das Löschen bestimmter NPM-Pakete dokumentieren zu müssen, damit die Hooks auf magische Weise anfangen zu arbeiten ...

Die Lösung zum Entfernen des Moduls react des verknüpften Pakets funktioniert nicht, wenn dieses Paket Tests enthält, die react erfordern (z. B. @testing-library/react oder @testing-library/react-hooks ), also es Es sieht so aus, als bräuchten wir noch einen besseren Weg, damit umzugehen.

Meine Bewerbung besteht aus zwei Teilen. Die Hauptwebanwendung und ein Modul, das dynamisch in die Webanwendung geladen wird. Sowohl die Webanwendung als auch das Modul verwenden React 16.9.0.
Das Modul wird mit React.lazy() und der dynamischen import()-Anweisung in die Webanwendung geladen.
Wenn das Modul geladen wird, wird der Fehler „Ungültiger Hook-Aufruf“ ausgegeben.

Da in meinem Fall die Hauptanwendung und das Modul separat erstellt werden, sind sie sich nicht bewusst und haben ihre eigene Kopie der Reaktion. Ich habe die folgenden Vorschläge im Thread ausprobiert, aber das Problem wurde nicht gelöst.

  1. Hinzufügen eines Alias ​​in der webpack.config des Moduls, der auf die Reaktion der Hauptanwendung verweist, wie von apieceofbart vorgeschlagen.
    alias: {
    reagieren: path.resolve('../../node_modules/react')
    }

  2. Es wurde versucht, die Reaktionsabhängigkeiten in der Datei „package.json“ des Moduls auf die Hauptanwendung zu verweisen.
    "Abhängigkeiten": {
    "react-dom": " file:../common/node_modules/react-dom ",
    "react": " file:../common/node_modules/react "
    }

Ich denke, React muss das Ausführen mehrerer Kopien unterstützen, wenn es um dynamisch geladene Module geht.

Basierend auf einigen der obigen Antworten hat Folgendes für mich funktioniert:

  1. Folgendes wurde zu config/webpack.config.js hinzugefügt
externals: {
  react: {
    root: 'React',
    commonjs2: 'react',
    commonjs: 'react',
    amd: 'react'
  },
  'react-dom': {
    root: 'ReactDOM',
    commonjs2: 'react-dom',
    commonjs: 'react-dom',
    amd: 'react-dom'
  }
}
  1. Bearbeitet package.json
"devDependencies" : {
  ...
  "react": "^16.9.0",
  "react-dom": "^16.9.0",
}
"peerDependencies": {
  "react": "^16.9.0",
  "react-dom": "^16.9.0"
}
  1. Bearbeitet public/index.html
<head>
  <script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
  <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
...

Danach konnte ich Hooks in meiner Bibliothek mit dem vom CDN geladenen React ausführen, während Jest immer noch die React-Kopie von node_modules (installiert von devDependencies) lud.

Ich hoffe, das hilft

Ich habe dieses Problem, wenn ich versuche, meine Komponente von einer funktionalen in eine klassische Komponente zu ändern, und ich erhalte auch diesen Fehler. Hier ist meine Lösung für diesen Fehler. Ich hoffe, es hilft auch in Ihrem Fall.

Versuchen Sie in diesem Fall, eine Komponente höherer Ordnung zu verwenden

Reagieren von 'Reagieren' importieren;
PropTypes aus 'prop-types' importieren;
import { withStyles } from '@material-ui/styles';
Schaltfläche aus '@material-ui/core/Button' importieren;

Konstante Stile = Thema => ({
Wurzel: {
Hintergrund: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
Grenze: 0,
RandRadius: 3,
boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)',
Farbe weiß',
Höhe: 48,
Polsterung: '0 30px',
},
});

Klasse HigherOrderComponent erweitert React.Component {

machen(){
const {classes} = this.props;
Rückkehr (
Komponente höherer Ordnung
);
}
}

HöhereOrderComponent.propTypes = {
Klassen: PropTypes.object.isRequired,
};

export default withStyles(styles)(HigherOrderComponent);

Ich verwende Yarn und habe dies behoben, indem ich die Auflösung in meinem package.json habe:

  "resolutions": {
    "**/react": "16.7.0-alpha.2",
    "**/react-dom": "16.7.0-alpha.2"
  },

Haben Sie das Eltern- oder Kinderpaket hinzugefügt?

Basierend auf einigen der obigen Antworten hat Folgendes für mich funktioniert:

  1. Folgendes wurde zu config/webpack.config.js hinzugefügt
externals: {
  react: {
    root: 'React',
    commonjs2: 'react',
    commonjs: 'react',
    amd: 'react'
  },
  'react-dom': {
    root: 'ReactDOM',
    commonjs2: 'react-dom',
    commonjs: 'react-dom',
    amd: 'react-dom'
  }
}
  1. Bearbeitet package.json
"devDependencies" : {
  ...
  "react": "^16.9.0",
  "react-dom": "^16.9.0",
}
"peerDependencies": {
  "react": "^16.9.0",
  "react-dom": "^16.9.0"
}
  1. Bearbeitet public/index.html
<head>
  <script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
  <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
...

Danach konnte ich Hooks in meiner Bibliothek mit dem vom CDN geladenen React ausführen, während Jest immer noch die React-Kopie von node_modules (installiert von devDependencies) lud.

Ich hoffe, das hilft

Nichts für ungut, aber es ist beunruhigend, dass Lösungen wie diese befolgt werden müssen. Ich habe in den letzten Tagen versucht, diesen Fehler zu beheben, ohne mich auf solche Hacks zu verlassen.

Ich arbeite an einer wiederverwendbaren Bibliothek, die Komponenten mit Hooks enthält. Ich muss sie in tatsächlichen Projekten testen, bevor ich sie veröffentliche. Die einzige Lösung dafür ist die Verwendung yarn|npm link . Ich bündele die Bibliothek mit Rollup und kann überprüfen, ob das Bündel keine Version von „react“ enthält. Wenn ich die App bündele (Webpack), die die Bibliothek verwendet, tritt der Fehler/das Problem auf. Dies geschieht auch für reine create-react-app - und next.js -Apps. Beide Frameworks verwenden Webpack im Hintergrund.

Hat jemand schon eine nachhaltige Lösung gefunden?

Indem ich npm|yarn link komplett aufgegeben habe, konnte ich das Problem lösen. Stattdessen verwende ich diese schöne Bibliothek, die unabhängig von Ihrer Projektstruktur ist. Außerdem können Sie webpack weiterhin als Bundler verwenden, sodass Sie _react_ und _react-dom_ nicht als external oder alias deklarieren müssen. Leider führt es einige neue Verzeichnisse und Sperrdateien in das Projekt ein, aber hey, es funktioniert ... lokal und sogar in unseren Docker-Containern.

Vielleicht ist dies bei der Liste ein wenig hilfreich:

Verknüpfung

@GabrielBB danke, es ist Arbeit für mich

@dmart914 danke! Bisher der einzige Workaround, der bei mir funktioniert :)

Derzeit wird die Warnung React Invalid Hook Call angezeigt, wenn ein minimales, einfaches Setup verwendet wird.

Diese Funktionskomponente:

  1. Verwendet dieselbe Version für React und ReactDOM.
  2. Folgt den Hakenregeln.
  3. Hat nur eine Kopie von React.

__Abhängigkeiten__
[email protected]
[email protected]
[email protected]
[email protected]

Und webpack test.js -o main.js , um zu bauen.

Ich erwarte von dieser Datei:

  • Rendern Sie die Box.

    • Halten Sie den Debugger an, bevor Sie React.useState aufrufen.

    • Erstellen Sie einen booleschen test und aktualisieren Sie den Callback updateTest .

    • Löst den React-Fehler aus.

    • Führen Sie beim Rendern die React.useEffect -Callbacks aus.

    • Löst den React-Fehler aus.

Mache ich etwas falsch, oder geht da noch was?

// test.js
import React, { createElement as el } from 'react';
import ReactDOM from 'react-dom'; 

function Item() {
  debugger;
  const [test, updateTest] = React.useState(false); // Throws React error.

  React.useEffect(function checkTest() { // Throws React error.
    console.log("checking test", test);
  }, [test]);

  React.useEffect(function tester() { // Throws React error.
    if (!test) {
      setTimeout(() => {
        console.log("changing value for test");
        updateTest(true);
      }, 1000);
    }
  }, [test]);

  return el('div', {style: {width: '300px', height: '300px', 'background-color': 'green', border: '1px solid red'}});
}

function render() {
  let root = document.querySelector('#primary');
  if (!root) {
    root = document.createElement('div');
    document.body.appendChild(root);
  }

  ReactDOM.render(Item(), root);
}

render();

Sie haben vergessen, tatsächlich ein Element zu erstellen. Sie rufen synchron Item() , bevor Sie den Aufruf $#$ ReactDOM.render erreichen. Sie müssen el(Item) passieren.

Wahr! Danke für die Info.

Bin in einer ähnlichen Situation wie einige der anderen Kommentatoren. Ich verwende Webpack, um einige Reaktionskomponenten (von denen einige Hooks verwenden) zu transpilieren und den transpilierten Code in einen Ordner lib zu legen. Ich habe „react“ zum Feld „ externals “ der Webpack-Konfiguration hinzugefügt, damit es nicht mit dem Komponentencode gebündelt wird. Ich möchte diese Komponenten in zwei getrennten Projekten verwenden – diese Komponenten sind ihnen gemeinsam und daher möchten wir sie an einem Ort entwickeln und die Aktualisierungen in beiden Apps widerspiegeln.

Wenn die Abhängigkeit mit common-components: file:../../common-components/lib in package.json hinzugefügt wird, werden die Komponenten perfekt geladen, aber das Ausführen von Webpack aktualisiert die Komponenten nicht sofort – stattdessen muss ich yarn upgrade common-components ausführen und dann den Dev-Server neu starten.

Wenn die Abhängigkeit mit common-components: link:../../common-components/lib hinzugefügt wird, aktualisiert das erneute Ausführen von Webpack die Dateien in node_modules der Haupt-App (da sie jetzt einen Symlink verwendet), aber ich erhalte den obigen Fehler von mehreren Instanzen von reagieren. Ich nehme an, es verwendet jetzt die Reaktionsversion im Ordner common-components/node_modules .

Gibt es eine Möglichkeit, Symlinks (dh common-components: link:../../common-components/lib ) zu verwenden und gleichzeitig sicherzustellen, dass die verknüpften Komponenten die Reaktion verwenden, die sich im Ordner node_modules der Haupt-App befindet? Da ich beabsichtige, diese Komponenten in beiden Apps zu verwenden, kann ich das React-Paket von einer von ihnen nicht mit der gemeinsamen Komponentenbibliothek verknüpfen, und ich möchte vermeiden, die Reaktionen beider Haupt-Apps mit der im gemeinsamen Komponentenpaket verwendeten zu verknüpfen. Ich habe einige Kommentare gesehen, die sich auf das Feld webpack resolve beziehen, was vielversprechend klingt, aber ich kann es nicht zum Laufen bringen. Jede Hilfe wäre sehr willkommen!

Bearbeiten: Für alle, die an unserem Anwendungsfall interessiert sind, haben wir den Build-Schritt geändert, um die Dateien einfach in die beiden Projekte zu kopieren, in denen sie benötigt werden, und das Transpilieren insgesamt zu vermeiden.

Eine schnelle Problemumgehung wäre, das Paket nicht zu veröffentlichen, sondern es einfach auf github zu pushen und es mit yarn add <git-url> in Ihr Projekt zu importieren.

Eine schnelle Problemumgehung wäre, das Paket nicht zu veröffentlichen, sondern es einfach auf github zu pushen und es mit yarn add <git-url> in Ihr Projekt zu importieren.

Der Grund, warum viele von uns npm link und npm package relative path verwenden, besteht darin, den Code zu entwickeln und zu testen, ohne Änderungen an NPM oder GitHub veröffentlichen zu müssen, bevor wir wissen, dass er funktioniert.

Wir sind auf dieses Problem gestoßen, das mit https://github.com/facebook/react/issues/13972#issuecomment -447599035 zusammenhängt, da ich denke, dass dies auch durch einen Webpack-Node-Server verursacht werden kann. Unser Anwendungsfall war ein Integrationstest, der innerhalb von Jest ausgeführt wurde und webpack() programmgesteuert ausführte, um den Server vor der Ausführung der Tests zu erstellen. Ich glaube, das Problem hängt damit zusammen, wie ESM und CJS gleichzeitig existieren können.

Nehmen Sie zum Beispiel dieses Beispiel:

// node express server, doing server-rendering
import React from 'react';
import { ApolloProvider } from '@apollo/react-common';
import { renderToStringWithData } from '@apollo/react-ssr';

res.send(await renderToStringWithData(<ApolloProvider><App /></ApolloProvider>)

Was ich während einer Debugger-Sitzung sehe, ist, dass wir zwei verschiedene Instanzen von React in der kompilierten Version dieser Datei erhalten können:

_react: {Children, ...}
_react2: {default: {Children, ...}

Woher
_react stammt aus dem ESM import React from 'react' in dieser Datei
_react2 stammt aus dem CJS var _react = _interopRequireDefault(require("react")); innerhalb von node_modules/@apollo/react-ssr/lib/react-ssr.cjs.js

Ich glaube, dies hat dazu geführt, dass der Verweis auf React an den beiden Stellen (Server-Render-Datei und innerhalb des Bundles @apollo/react-ssr ) nicht gleich war und somit der Fehler ausgelöst wurde.

Wir haben festgestellt, dass dies wahrscheinlich durch die programmgesteuerte Verwendung von webpack() innerhalb des Tests verursacht wurde, und haben diese Tests in End-to-End-Tests umgestaltet. Die Lektion für uns ist, dass Sie möglicherweise übermäßig komplizierte Tests haben, wenn das Problem nur im Testcode auftritt.

Ich habe es geschafft, es mit Garn zu lösen:

cd zu myApp/node_modules/react und yarn link

Führen Sie dann in Ihrer Bibliothek yarn link react aus

Jetzt verwendet Ihre Bibliothek genau dieselbe Reaktionsversion wie Ihre Haupt-App

Ich habe versucht, React als Peer-Abhängigkeit in meiner Lib festzulegen, aber dann wurde die Lib nicht erstellt

Wie kann man das mit create-react-app beheben, ohne auszuwerfen oder zu yarn zu wechseln?

Sie können genau dieselbe Technik mit npm link verwenden. Kein Auswerfen notwendig.

Das Verknüpfen react ist nicht die beste Idee, wenn Sie an mehreren Projekten mit unterschiedlichen Versionen arbeiten.

@woles du hast völlig recht, aber in meinem Fall löst es mein Hakenproblem. Ich hoffe, dass die React-Entwickler eine bessere Lösung finden

Hallo,
Ich habe diesen Fehler nach Stunden behoben, als mir klar wurde, dass ich die Komponente versehentlich fälschlicherweise im React-Router verwendet habe.

Meine App funktionierte, aber in einer Komponente konnte ich useState überhaupt nicht hinzufügen. Der Grund war, dass ich die Rendermethode der Komponente innerhalb der React-Router ohne die Funktion höherer Ordnung wie folgt verwendet habe:
<Route exact path="/path" render={ ComponentCausingTheErrorMesage }/>
wechseln zu
<Route exact path="/path" component={ ComponentNowWorkingAgain }/>
hat es für mich behoben

Ich habe npm link zwischen einer App und einem Modul verwendet, an dem ich aktiv gearbeitet habe, und ich musste das Problem beheben, indem ich die react und react-dom der App mit dem Modul verknüpfte und dann verknüpfte das Modul zur App:

im Programm:

  1. cd node_modules/react && npm link
  2. dasselbe für react-dom

im Modul:

  1. npm link react && npm link react-dom
  2. npm link

im Programm:

  1. npm link [module-name]

Hoffe, das hilft jemandem

Wir hatten Hooks, die clientseitig funktionierten, aber diesen Fehler traten bei SSR auf. Mein Kollege hat dies mit folgendem in unserer serverseitigen Webpack-Konfiguration gelöst:

const nodeExternals = require('webpack-node-externals');

const serverConfig = () => {
  // lots of config, then:
  externals: [
    nodeExternals({
      modulesFromFile: true,
    }),
  ],
}

Ich habe es geschafft, es mit Garn zu lösen:

cd zu myApp/node_modules/react und yarn link

Führen Sie dann in Ihrer Bibliothek yarn link react aus

Jetzt verwendet Ihre Bibliothek genau dieselbe Reaktionsversion wie Ihre Haupt-App

Ich habe versucht, React als Peer-Abhängigkeit in meiner Lib festzulegen, aber dann wurde die Lib nicht erstellt

Das funktioniert einfach wunderbar

Ich bin gerade auf dieses Problem gestoßen, als ich gleichzeitig Electron-Webpack, React und Material-UI verwendet habe. Wenn ich versuche, etwas von material-ui zu verwenden, erhalte ich diesen Fehler (z. B. versuchen, eine

Hallo ZVER3D, versuchen Sie, meinen früheren Kommentar zu lesen. Ich hoffe es hilft!

Ich habe npm link zwischen einer App und einem Modul verwendet, an dem ich aktiv gearbeitet habe, und ich musste das Problem beheben, indem ich die react und react-dom der App mit dem Modul verknüpfte und dann verknüpfte das Modul zur App:

im Programm:

1. `cd node_modules/react && npm link`

2. same for `react-dom`

im Modul:

1. `npm link react && npm link react-dom`

2. `npm link`

im Programm:

1. `npm link [module-name]`

Hoffe, das hilft jemandem

Süßer Baby Mose, das hat mir so sehr geholfen. Ich habe nicht einmal daran gedacht, dass das Problem unterschiedliche Versionen von React sind !! Ich erstelle lokal eine Komponente, um sie in NPM zu veröffentlichen, habe aber ein separates Projekt, um sie lokal zu testen, indem ich npm link verwende. Offensichtlich verwenden sie (jetzt) ​​beide unterschiedliche Versionen von React. D'oh!

Hallo ZVER3D, versuchen Sie, meinen früheren Kommentar zu lesen. Ich hoffe es hilft!

Danke, dass du mich in die richtige Richtung weist. Eine andere Lösung bestand darin, die ui-Bibliothek, die ich verwende, in "whiteListedModules" hinzuzufügen. Das einzige Problem wäre, dass Sie dies für alle Module tun müssten, die zum Kompilieren reagieren müssen.
Also, in package.json habe ich Folgendes geschrieben:

"electronWebpack": {
    "whiteListedModules": [
      "@material-ui/core",
      "@material-ui/icons"
    ]
  }

Ich entwickle eine React-Anwendung mit dem Monorepo-Ansatz. Ich habe eine Hauptanwendung ( brush ) und eine Reaktionsbibliothekskomponente ( react-gbajs ).

Wenn ich also versuche, meine react-gbajs -Komponente zu rendern, erhalte ich diesen Fehler bezüglich mehrerer Instanzen von React. Wenn ich denselben Code kopiere und auf brush einfüge, habe ich kein Problem.
Ich habe viele Ansätze verfolgt, um das Problem zu beheben, aber keiner von ihnen hat es gelöst (Änderung des Builds auf Webpack, Yarns Arbeitsbereich, npm-Link ...)

Ich habe versucht zu debuggen, um zu überprüfen, ob ich wirklich zwei Kopien von React habe (mit console.log(window.React1 === window.React2) aus Reacts Dokument), aber es wird als true ausgewertet!
(Eine SEHR SCHLECHTE Problemumgehung, die ich jetzt verwende, besteht darin, die Haken als Stütze zu übergeben: <GBAEmulator useEffect={useEffect} /> ... aber ich möchte es wirklich nicht zusammenführen.)

Hat jemand eine Idee zur Behebung?

Mein Projekt ist Open Source und ich füge diese neue Reaktionsbibliothekskomponente in diesem Zweig hinzu: https://github.com/macabeus/klo-gba.js/blob/ac18f4d42b122c333622f502947135c2de217ce2/react-gbajs/src/index.js#L251 -L274

Hallo alle,

Ich habe eine App (myApp), die als Abhängigkeit eine benutzerdefinierte Bibliothek (myDepPackage) verwendet. Beide verwenden Webpack als Build-Tool und natürlich hatte ich den gleichen Fehler. Keine der oben genannten Lösungen hat bei mir funktioniert. Was es getan hat, war, webpack zu zwingen, React NICHT in das endgültige Bundle der benutzerdefinierten Bibliothek (myDepPackage) aufzunehmen. Die einzige Konfigurationszeile, die ich zur Webpack-Konfiguration (des myDepPackage) hinzufügen musste, ist die folgende:

externals: {
  react: "react",
},

Hier erfahren Sie mehr über die Option „externals“: https://webpack.js.org/configuration/externals/#externals

@tsevdos Veeeery danke!!! ❤️
Es hat mein Problem gelöst, das ich im vorherigen Kommentar gesagt habe.

Für uns bestand das Problem darin, dass wir eine einbettbare React-App haben, die von einem WordPress-Shortcode in die Seite geladen und auf einem Div mit einer zufälligen ID gemountet wird. Auf einigen Seiten haben wir mehrere eingebettete Apps und es hat gut funktioniert, bis wir anfingen, Hooks zu verwenden.

Es würde sich nur auf Seiten mit mehreren eingebetteten Apps beschweren, daher bestand die Lösung darin, den WP-Shortcode zu aktualisieren, um das Skript nur einmal mit dem Build zu laden.

Klingt einfach und offensichtlich, war aber schwierig herauszufinden! Vor allem, weil es das tat und gut funktionierte, bis wir Hooks hinzufügten.

Interessanterweise haben wir auf einigen Seiten andere - andere - Apps, die wir einbetten, die ebenfalls Hooks verwenden, und sie laden auch ihr eigenes Skript/Build mit React, ... aber dann funktioniert es gut! Das Problem bestand darin , dass genau derselbe Build mehr als einmal geladen wurde und Hooks verwendet wurden .

Was für mich funktioniert hat, war eine Kombination aus zwei Vorschlägen aus diesem Problemthread.

Webpack-Konfiguration der Hauptanwendung ( Vorschlag von @apieceofbart )

  resolve: {
    alias: {
      react: resolve('./node_modules/react')
    }
  }

Webpack-Konfiguration von Dependency ( Vorschlag von @tsevdos )

  externals:
    react: 'react'
  }

Ich hatte dieses Problem mit html-webpack-plugin und ich verwendete index.html sieht so aus als template bis HtmlWebpackPlugin Einstellung.

// webpack.config.js
plugins: [
   new HtmlWebpackPlugin({
      template: "./public/index.html"
   })
],
<!-- public/index.html -->
<html>
<head>
    <title>React App</title>
</head>
<body>
    <div id="root"></div>
    <script src="main.js"></script>
</body>

</html>

Mir wurde klar, dass das Plugin <script type="text/javascript" src="main.js"></script> direkt nach <div id="root"></div> injizierte.

Also, als ich das Dev-Tool öffnete und HTML generierte, sah es so aus.

<html>
<head>
    <title>React App</title>
</head>
<body>
    <div id="root"></div>
    <script src="main.js"></script>
    <script type="text/javascript" src="main.js"></script> <!-- injected from html-webpack-plugin -->
</body>

</html>

Bei mir hat das Invalid Hook Call Warning verursacht.

Ich konnte die Warnung entfernen, indem ich <script src="main.js"></script> wie unten entfernt habe.

<!-- public/index.html -->
<html>
<head>
    <title>React App</title>
</head>
<body>
    <div id="root"></div>
</body>

</html>

Ich hoffe, es hilft jemandem, der nach einer Lösung sucht!

Beachten Sie, dass auch React-abhängige Bibliotheken diese Probleme verursachen können. In meinem Fall habe ich verschiedene Versionen von @emotion/core und @emotion/styled verwendet.

https://github.com/emotion-js/emotion/issues/1470

Hallo,

Eine mögliche Lösung ohne Auswerfen ist das Mischen der Webpack-Alias-Konfigurationslösung mit Customize-Cra- und React-App-Rewired- Bibliotheken. Auf diese Weise können Sie nur die notwendige Webpack-Konfiguration überschreiben, um das Problem zu lösen, indem Sie eine config-overrides.js-Datei erstellen mit:

const { override, addWebpackAlias } = require('customize-cra');
const path = require('path');

module.exports = override(
  addWebpackAlias({
    react: path.resolve(path.join(__dirname, './node_modules/react')),
  }),
);

Ich hatte dieses Problem auf einer Gatsby-Site, ich habe npm install ausgeführt und auf die neueste Version von Gatsby aktualisiert, und es hat alles behoben

Wenn Sie ein Problem mit Scherztests haben, die yarn or npm test (wie ich es war) und react-test-renderer verwenden, stellen Sie sicher, dass react-test-renderer mit derselben Version von react $ übereinstimmt du benutzt.

Beispiel:

// Package.json
{
  ...
    "react" : "16.8.3",
  ...
}

Führen Sie yarn add [email protected]

Ich habe eine Bibliothek und ich habe alle Versionen von react und react-dom sowohl in der Bibliothek als auch in den Hauptprojekten überprüft. Sie sind genau gleich, aber haben nicht funktioniert.
Die @apieceofbart- Lösung hat jedoch für mich funktioniert.

@apieceofbart , du hast meinen Tag gerettet <3

Was für mich funktioniert hat, war eine Kombination aus zwei Vorschlägen aus diesem Problemthread.

Webpack-Konfiguration der Hauptanwendung ( Vorschlag von @apieceofbart )

  resolve: {
    alias: {
      react: resolve('./node_modules/react')
    }
  }

Webpack-Konfiguration von Dependency ( Vorschlag von @tsevdos )

  externals:
    react: 'react'
  }

Hier gilt das gleiche. Ich muss diese beiden Korrekturen durchführen, damit es funktioniert. Meine Erklärung ist, dass die zweite Konfiguration der Abhängigkeit mitteilt, externe Reaktionen mit dem Namen „react“ zu verwenden, und die erste Konfiguration den Namen „react“ auf den Ordner „node_modules/react“ im Haupt-Repository verweist. Daher sind beide notwendig, damit die Reaktionsbrücke funktioniert.

Trotzdem scheint es, dass für manche Leute einer von ihnen genug ist, was ich nicht wirklich verstehe.

Was für mich funktioniert hat, war eine Kombination aus zwei Vorschlägen aus diesem Problemthread.
Webpack-Konfiguration der Hauptanwendung ( Vorschlag von @apieceofbart )

  resolve: {
    alias: {
      react: resolve('./node_modules/react')
    }
  }

Webpack-Konfiguration von Dependency ( Vorschlag von @tsevdos )

  externals:
    react: 'react'
  }

Hier gilt das gleiche. Ich muss diese beiden Korrekturen durchführen, damit es funktioniert. Meine Erklärung ist, dass die zweite Konfiguration der Abhängigkeit mitteilt, externe Reaktionen mit dem Namen „react“ zu verwenden, und die erste Konfiguration den Namen „react“ auf den Ordner „node_modules/react“ im Haupt-Repository verweist. Daher sind beide notwendig, damit die Reaktionsbrücke funktioniert.

Trotzdem scheint es, dass für manche Leute einer von ihnen genug ist, was ich nicht wirklich verstehe.

Der zweite Punkt ist wichtig!
Wenn es ignoriert wird, wird das React beim Build-Prozess zusammen exportiert, da es sich um eine interne Abhängigkeit handelt

viel liebe @apieceofbart !!!! Ich war kurz davor, meinen Schreibtisch durch die Wand zu treten

Es gibt also noch keine Problemumgehung für Microservices. Ich habe eine Root-Anwendung mit React, die dynamisch Bundles mit einem anderen React erfordert. Wir können nicht einfach eine externe Version von React verwenden, da es viele unabhängige Teams mit ihren eigenen Abhängigkeiten gibt. Wenn wir sie dazu drängen, dieselbe externe Version zu verwenden, werden die meisten Projekte offensichtlich abstürzen und es wird unmöglich, diese Version zu aktualisieren, da jedes Projekt von dieser Version abhängt.

Irgendwelche Ideen?

Gibt es eine Lösung für die Verwendung von Reaktionshaken zusammen mit npm-Link, die kein Auswerfen aus CRA erfordert?

@Schellenbach
Sie können Craco verwenden, um die CRA-Konfiguration ohne Auswerfen zu überschreiben.
https://github.com/gsoft-inc/craco

Dank @tsevdos habe ich mein Problem gelöst und ein Tutorial zum Erstellen eines React-Pakets erstellt: https://youtu.be/esyS87NfBOw

Ich habe dieses Problem erhalten und die Webpack-Lösung wurde nicht angewendet, da ich stattdessen den Paketbündelr verwende. Ich konnte es beheben, indem ich einen Alias ​​in der package.json meiner Haupt-App angab, der so aussah

    "alias": {
        "react": "./node_modules/react",
        "react-dom": "./node_modules/react-dom"
    },

Probleme beim Versuch, meine React-Komponenten (in Hooks geschrieben) in einer Elektron-App im selben Projekt mit einem anderen Paket-json zu verwenden. Die Dateistruktur sieht wie folgt aus:

- javascript
  - src
     - ComponentIWantToUse.tsx
      - package.json
- electron
   - src
     - IwantToUseItHere.tsx
      - package.json

Beide package.json enthalten „react“ und „react-dom“ in „package.json“, aber sie sind die gleichen Versionen, und ich sehe nicht, dass zwei React-Installationen angezeigt werden, wenn ich npm ls react mache. Irgendwelche Ideen?

BEARBEITEN: Die Lösung von @ewan-m hat funktioniert!

Also bin ich auf einen seltsamen Fall gestoßen, glaube ich. Eine Bibliothek eines Drittanbieters hat leider gemischte funktionale und klassenbasierte Komponenten. Meine Komponenten in meiner Codebasis sind funktionsfähig. Eine klassenbasierte Komponente aus der Bibliothek fungiert als Layout, das meine Komponente als Kind darstellt. Ich glaube, das ist es, was den „Error: Invalid Hook Call“ auslöst. Wie sollte ich das umgehen, um Hooks zu verwenden, muss ich meine in eine Klassenkomponente konvertieren?

@GrandathePanda Das Mischen von Klassen und funktionalen Komponenten sollte keine Rolle spielen. Wenn eine Klasse eine Funktion aufruft, die einen Hook aufruft, gibt es dort kein Problem. Das einzige, was Sie nicht tun können, ist, einen Hook direkt aus der Klasse heraus aufzurufen.

Okay, @JeremyGrieshop , dann muss ich noch etwas nachforschen, wenn ich rendere, ohne die Drittanbieterkomponente zu verwenden, wird es gut gerendert, also gibt es dann einen Konflikt zwischen dieser Bibliothek und meinem Code. Wenn ich raten müsste, verwenden sie vielleicht eine andere Reaktionsversion in ihrem Paket.

Okay, @JeremyGrieshop , dann muss ich noch etwas nachforschen, wenn ich rendere, ohne die Drittanbieterkomponente zu verwenden, wird es gut gerendert, also gibt es dann einen Konflikt zwischen dieser Bibliothek und meinem Code. Wenn ich raten müsste, verwenden sie vielleicht eine andere Reaktionsversion in ihrem Paket.

Richtig, überprüfen Sie npm ls react react-dom in Ihrer App, um zu sehen, ob es mehrere Versionen gibt. Es ist möglich, dass die Bibliothek des Drittanbieters eine Abhängigkeit von einer bestimmten Version hat.

@JeremyGrieshop Es sieht also so aus, als ob meine Anwendung 16.12.0 für React und Dom verwendet und der Drittanbieter (Elastic Search-UI) 16.8.0 für React und Dom verwendet. Wenn ich richtig liege, besteht das Problem darin, dass, da meine 16.8.0-Drittanbieterbibliothek die mit 16.12.0 erstellte Komponente rendert, dies das Problem verursacht? Sie sind auch ein Lerna Monorepo, was dies möglicherweise noch komplizierter macht, nachdem Sie alle obigen Kommentare gelesen haben. Das Problem ergibt sich aus einem in materialui erstellten useStyles-Hook, sie liefern einen withStyles-Hoc für die Abwärtskompatibilität, und ich denke, in der Zwischenzeit werde ich diesen Weg gehen. Alle oben erwähnten Änderungen an Webpack und/oder dem Paket json scheinen wirklich wie ein Pflaster zu sein, das eher kaputt geht, als in der Zwischenzeit einfach mit einem klassischen Hoc zu gehen, während Hooks herausfinden, wie sie angesichts so vieler verschiedener Implementierungsschwierigkeiten reifen können.

@GrandathePanda IMHO, Ihre Optionen sind (1) den Drittanbieter dazu zu bringen, entweder seine Reaktionsabhängigkeit auf 16.12 zu aktualisieren oder ihn entscheiden zu lassen, ob es besser geeignet ist, es als PeerDependency zu haben als eine Abhängigkeit; (2) Verwenden Sie 16.8 in Ihrer App, damit sie dieselben Lib-Versionen teilen; (3) Beseitigen Sie ihre Kopie der Reaktion mit:

rimraf node_modules/search-ui/node_modules/react && rimraf node_modules/search-ui/node_modules/react-dom

Der obige Befehl kann in „prebuild“ und „prestart“ unter dem „scripts“-Teil Ihrer package.json platziert werden (was ich gerade tue). Der Nachteil von (3) ist, nehme ich an, wenn sie etwas veraltetes zwischen 16.8 und 16.12 verwenden.

Hallo alle,

Ich habe eine App (myApp), die als Abhängigkeit eine benutzerdefinierte Bibliothek (myDepPackage) verwendet. Beide verwenden Webpack als Build-Tool und natürlich hatte ich den gleichen Fehler. Keine der oben genannten Lösungen hat bei mir funktioniert. Was es getan hat, war, webpack zu zwingen, React NICHT in das endgültige Bundle der benutzerdefinierten Bibliothek (myDepPackage) aufzunehmen. Die einzige Konfigurationszeile, die ich zur Webpack-Konfiguration (des myDepPackage) hinzufügen musste, ist die folgende:

externals: {
  react: "react",
},

Hier erfahren Sie mehr über die Option „externals“: https://webpack.js.org/configuration/externals/#externals

@tsevdos Ich liebe dich. Sie haben gerade einigen Tagen intensiven Ärgers ein Ende gesetzt. Danke.

Hallo allerseits,

Ich versuche, einen Hook in einer Komponente zu verwenden, diese Komponente soll aus gatsby-browser.js exportiert werden.

Wie ist das aktuelle Verhalten?

Ich bekomme diesen Fehler:

Unbehandelte Ablehnung (Fehler): Ungültiger Hook-Aufruf. Hooks können nur innerhalb des Körpers einer Funktionskomponente aufgerufen werden. Dies kann aus einem der folgenden Gründe geschehen:

  1. Möglicherweise haben Sie nicht übereinstimmende Versionen von React und dem Renderer (z. B. React DOM).
  2. Sie könnten die Hook-Regeln brechen
  3. Möglicherweise haben Sie mehr als eine Kopie von React in derselben App
    Unter https://fb.me/react-invalid-hook-call finden Sie Tipps zum Debuggen und Beheben dieses Problems.

Dies ist ein Beispielcode:

import React from 'react';
import PropTypes from 'prop-types';
import { Provider } from 'react-redux';

import configureStore from './src/utils/configure-store';
import { useApiResources } from './src/hooks/use-api-resources';

const RootWrapper = ({ element }) => {
  const resources = useApiResources();
  const store = configureStore();
  return <Provider store={store}>{element}</Provider>;
};

RootWrapper.propTypes = {
  element: PropTypes.node.isRequired,
};

export default RootWrapper;

Was ist das erwartete Verhalten?

Hook sollte fehlerfrei laufen oder nützliche Fehlermeldungen liefern.

Versionen der React- und React-Dom-Abhängigkeiten sind 16.12.0

@leejh3224 vielen Dank Alter! Nach stundenlanger Suche fand ich diese Antwort, sie löste mein Problem.
Habe gerade die HtmlWebpackPlugin Config von geändert
inject: true bis inject: 'head' und die minimierten Reaktionsfehler sind weg.

Ich habe eine Stackoverflow-Frage mit meiner Erfahrung erstellt, wie ich versucht habe, dies zum Laufen zu bringen. Wäre es möglich, dass diejenigen, die es geschafft haben, dies zum Laufen zu bringen, es sich ansehen und Ratschläge geben?

Ich portiere eine jquery-Anwendung auf React. Ich habe ein Dienstprogramm, um React-Komponenten in jQuery namens asJqueryPlugin zu machen. Hier ist die Datei:

import React from 'react'
import ReactDOM from 'react-dom'

/**
 * A way to render React components with props easily with jQuery
 *
 * ## Register the React Component
 *
 * In your React Component file, register the component with jQuery using `asJqueryPlugin`
 * ```
 * const Greeting = ({ person }) => <div>Hello {person}</div>
 * asJqueryPlugin('Greeting', Greeting, { person: "Bob" })
 * ```
 *
 * ## Rendering, Selecting and Updating Props with jQuery
 *
 * Select an element and render using the `react` function
 * ```
 * $('#greeting').react('Greeting', { person: 'Frank' })
 * ```
 */

window.reactRegistry = window.reactRegistry || {}

// This is how React components register themselves as available within jQuery
export default function asJqueryPlugin(componentName, Component) {
  window.reactRegistry[componentName] = { Component }
}

if (typeof window.$ !== 'undefined') {
  ;(function($) {
    // Add the plugin function jQuery
    $.fn.react = function renderReactIntoElements(componentName, props) {
      this.each(function render() {
        const entry = window.reactRegistry[componentName || $(this).data('react')]
        if (!entry) throw Error(`${componentName} component is not registered.`)
        ReactDOM.render(<entry.Component {...props} />, this)
      })
      return this
    }
  })(window.$)
}

Die App hat viele Einstiegspunkte in Webpack, und etwa 3-4 Komponenten verwenden diese Technik jetzt. Wenn Komponenten in verschiedenen Einstiegspaketen gebündelt werden, tritt das Problem meiner Meinung nach auf.

Wenn ich also zwei Einstiegspunkte in Webpack habe:

entry: {
      foo: './assets/js/foo',
      bar: './assets/js/bar'
}

Dann richten wir in jeder dieser Dateien eine exponierte Komponente ein (jede mit Hooks):

// foo.js
import React from 'react'
import asJqueryPlugin from '../utils/asJqueryPlugin'
const Foo = () => {
  const ref = useRef()
  return <div ref={ref}>Foo</div>
}
asJqueryPlugin('Foo', Foo)

// bar.js
... same stuff but with Bar component

Wenn ich nun beide Einträge auf derselben Seite einfüge und versuche, beide Komponenten über das jquery-Plugin zu rendern ...

<script src="/bundles/foo.js" />
<script src="/bundles/bar.js" />
<script>
    $('#foo-container').react('Foo')
    $('#bar-container').react('Bar')
</script>

... Ich erhalte diesen Hooks-Fehler.

Ich bin mir nicht sicher, ob dies der Konversation hilft oder nicht, zeigt aber zumindest einen Anwendungsfall, wie ein (fraglich) gesunder Entwickler in eine Situation mit mehreren Reaktionsinstanzen geraten könnte.

Das hat mir geholfen - https://github.com/facebook/react/issues/13991#issuecomment -554928373
Aber ich musste auch react und react-dom aus den Abhängigkeiten entfernen und sie in Peer-Abhängigkeiten verschieben und Knotenmodule deinstallieren und neu installieren.

Hallo,
Ich habe das Gespräch und viele Beiträge im Internet gelesen und stecke immer noch mit dem Fehler fest, dass mehrere Instanzen reagieren.
Ich pushe dieses Repo, um den Fehler zu reproduzieren: https://github.com/jeromelegrand/dooliz-lib
Ich hoffe jemand kann mir helfen.
Danke.

Ich stehe vor diesem Problem und komme mit den oben genannten Lösungen nicht weiter.
Kurz gesagt: Ich bin mir sehr sicher, dass nur eine React-Version läuft, und ich erhalte den Fehler mit React-Bootstrap, der Hooks wahrscheinlich nicht falsch verwendet, weil sonst niemand Probleme hat.

Dieser Fehler tritt bei mir in einem node.js-Backend auf.

__Was ich in Bezug auf Reaktionsversionen überprüft habe__

Ich habe ein Garn-Setup mit Arbeitsbereichen, yarn list react oder yarn list react-dom zeigt nur eine Instanz.

Ich habe "require cache" gedruckt, um zu sehen, was importiert wurde:

for(var key in require.cache) {
    if(key.indexOf("react") !== -1 && key.indexOf("index") !== -1) {
        console.log(key);
    }
}

Ich führe es aus, kurz bevor ich etwas von React-Bootstrap rendere, was den ungültigen Hook-Fehler für mich verursacht, und es protokolliert:

C:\web\resourceful\daCore\node_modules\react-dom\index.js
C:\web\resourceful\daCore\node_modules\react\index.js
C:\web\resourceful\daCore\node_modules\react-router-dom\index.js
C:\web\resourceful\daCore\node_modules\react-router-dom\node_modules\react-router\index.js
C:\web\resourceful\daCore\node_modules\react-is\index.js
C:\web\resourceful\daCore\node_modules\mini-create-react-context\dist\cjs\index.js
C:\web\resourceful\daCore\node_modules\react-router\index.js
C:\web\resourceful\daCore\node_modules\@fortawesome\react-fontawesome\index.js
C:\web\resourceful\daCore\node_modules\@tinymce\tinymce-react\lib\cjs\main\ts\index.js

Was zu bestätigen scheint, dass nur 1 Reaktionsversion geladen ist.

Schließlich habe ich dies zu node_modules/react-dom/index.js hinzugefügt

console.log("React DOM daCore");
global['React1'] = require('react');

Und dies nach node_modules/react-router-dom/cjs/Form.js

require('react-dom');
global['React2'] = require('react');
console.log('#TEST '+(global['React1'] === global['React2']? 'SAME' : 'NOT SAME'));

Was SAME druckt

Irgendeine Idee, was das noch sein kann?
Ich werde dies auch auf React-Bootstrap Repo posten.

Ich bin mir also ziemlich sicher, dass es hier nicht darum geht, zwei Instanzen von React zu haben. Ich denke, das Problem ist, wenn es zwei reagierende _roots_ gibt. Rufen Sie ReactDOM.render() mehrmals in verschiedenen Teilen der Seite auf? Wenn ja, denke ich, dass dies das Problem verursachen kann. Ich denke, Hooks "gehören" zu einer bestimmten "Root" und brechen, wenn es mehrere davon gibt und die beiden Bundles einen gemeinsamen Code haben. Ich vermute hier...

... Ich denke, das Problem ist, wenn es zwei reagierende _Roots_ gibt. Rufen Sie ReactDOM.render() mehrmals in verschiedenen Teilen der Seite auf?

Danke @timkindberg , das hat mir geholfen, es endlich zu lösen. Mir wurde klar, dass ich den React-Tree-Walker verwende, um ein erstes Rendering durchzuführen und die erforderlichen Daten abzurufen, bevor ich das endgültige Rendering mit ReactDOMServer.renderToString mache

Durch schnelles Entfernen der Verwendung dieses Pakets wurde der Fehler behoben, und ich habe jetzt dasselbe mit React-ssr-prepass zum Laufen gebracht, was jetzt tatsächlich auf der Readme-Seite von React-Tree-Walker empfohlen wird

Es waren also tatsächlich zwei ReactDOM.render Anrufe! Im Moment funktioniert dieses Setup mit React-SSR-Prepass für mich, und wenn Suspense in React-Dom/Server landet, kann ich darauf umschalten

Ich verwende react-compare-image https://github.com/junkboy0315/react-compare-image in meinem Gutenberg-Projekt, habe aber dieses seltsame Problem, obwohl alles funktioniert, wenn ich die Komponente ReactCompareImage aus der Speicherfunktion entferne. Die Edit-Funktion funktioniert einwandfrei, aber das Speichern funktioniert nicht.

Ich bin https://reactjs.org/warnings/invalid-hook-call-warning.html durchgegangen und glaube nicht, dass ich eines dieser Probleme habe.

Hier ist die vollständige Speicherfunktionsdatei:

```Inspektor aus "./inspector" importieren;
importiere { Fragment } aus "reagieren";
importiere ReactCompareImage aus "react-compare-image";

/**

  • WordPress-Abhängigkeiten
    */
    const {__} = wp.i18n;

const save = ({Klassenname, Attribute}) => {

const {
    paddingTop,
    paddingRight,
    paddingBottom,
    paddingLeft,

    marginTop,
    marginRight,
    marginBottom,
    marginLeft,

    border,
    borderColor,
    borderType,
    background,

    backgroundImage,
    gradient,

    dividerColor,
    buttonColor,

    direction,

    beforeImage,
    beforeLabel,
    afterImage,
    afterLabel,

} = attributes;

const style = {
    "padding": `${paddingTop}px ${paddingRight}px ${paddingBottom}px ${paddingLeft}px`,
    "margin": `${marginTop}px ${marginRight}px ${marginBottom}px ${marginLeft}px`,
    "border": `${border}px ${borderType} ${borderColor}`,
    "background": background
};

return(
    <Fragment>
        <ReactCompareImage
            leftImage={beforeImage.url}
            leftImageLabel={beforeLabel}
            rightImage={afterImage.url}
            rightImageLabel={afterLabel}
            vertical={'vertical' === direction}
            sliderLineColor={dividerColor}
        />
    </Fragment>
);

};

Standard speichern exportieren;
```
Screenshot 2020-02-19 at 4 11 52 PM

Ich stoße auch auf dieses Problem. Ich habe eine Zusammenfassung auf SO gepostet: https://stackoverflow.com/questions/60331304/next-js-with-typescript-invalid-hook-call-hooks-can-only-be-called-inside-of-t

Ich habe auch ein minimal reproduzierbares Beispiel: https://github.com/coler-j/shopify_playground

Meine Haupt-App ist eine create-react -App (nicht ausgeworfen), die eine gemeinsam genutzte Bibliothek importiert hat, die auch React verwendet. Ich konnte das lösen durch:

Verwenden von Rollup zum Packen der Bibliothek anstelle von Webpack
Aus irgendeinem Grund muss ich noch herausfinden, dass die Verwendung von Externals React nicht aus dem Bibliothekspaket entfernt hat.

rollup-config.js

export default [
  {
    input: 'src/index.js',
    output: {
      file: pkg.main,
      format: 'cjs',
      sourcemap: true,
    },
    plugins: [external(), babel(), resolve(), commonjs(), svgr()],
  },
  {
    input: 'src/index.js',
    output: {
      file: pkg.module,
      format: 'es',
      sourcemap: true,
    },
    plugins: [
      alias({
        entries: [{ find: '<strong i="12">@components</strong>', replacement: 'src/components' }],
      }),
      external(),
      babel(),
      svgr(),
    ],
  },
]

Craco installieren und damit das Webpack der Haupt-App ändern
craco.config.js

const path = require('path')

module.exports = {
  webpack: {
    alias: {
      react: path.resolve(__dirname, './node_modules/react'),
    },
  },
}

Danke an @arminyahya für den Hinweis auf craco.

Ich versuche, Hooks zu verwenden, während ich die Reaktion von einem CDN lade. Dieses Beispiel (das ist die gesamte HTML-Seite) gibt den Fehler Hooks can only be called inside of the body of a function component aus, wenn Example() aufgerufen wird. Ich habe alles entfernt, sogar ReactDOM, daher ist es schwer vorstellbar, dass ich mehrere Kopien von React haben könnte. Ist das einfach unmöglich?

<!DOCTYPE html>
<html>

<head>
  <script crossorigin src="https://unpkg.com/[email protected]/umd/react.development.js"></script>
  <script crossorigin src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>

</body>
  <script type="text/babel">
    function Example() {
      let [count, setCount] = React.useState(0);
      return ( <h1>Hello</h1> );
    };

  Example();
  </script>
</body>

</html>

@samkamin Das liegt daran, dass du NULL Reaktionswurzeln hast. Sie müssen Ihren Antrag stellen. Dies ist jedoch immer noch eine gute Bestätigung dafür, dass Hooks auf einer Reaktionswurzel beruhen (und an diese gekoppelt sind).

<html>
<head>
  <script crossorigin src="https://unpkg.com/[email protected]/umd/react.development.js"></script>
  <script crossorigin src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>
  <script crossorigin src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
</body>
  <div id="root"></div>
  <script type="text/babel">
    function Example() {
      let [count, setCount] = React.useState(0);
      return ( <h1>Hello</h1> );
    };

    ReactDOM.render(<Example />, document.getElementById('root'))
  </script>
</body>
</html>

Danke! Es war tatsächlich nicht das Fehlen einer React-Root - ich habe das nur entfernt, um den Fehler so weit wie möglich zu vereinfachen -, sondern etwas ebenso Dummes: Statt <Example /> habe ich nur Example() geschrieben

Nichts scheint bei mir zu funktionieren. Ich erstelle eine Komponente zur gemeinsamen Nutzung und Verwendung in anderen Projekten, aber das lokale Testen aus einem anderen Projekt funktioniert nicht. Ich verwende Hooks mit React 16.13.0.

webpack.config.js

module.exports = {
  entry: ENTRY,
  output: {
    library: LIBRARY_NAME,
    path: path.resolve(__dirname, OUTPUT_DIR),
    filename: OUTPUT_FILENAME,
    libraryTarget: 'commonjs2',
  },
  module: {
    rules: [
      {
        test: /\.(js|tsx)$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
      },
      {
        test: /\.tsx?$/,
        exclude: /node_modules/,
        use: 'ts-loader',
      },
    ],
  },
  resolve: {
    alias: {
      '<strong i="7">@src</strong>': path.resolve(__dirname, './src'),
      '<strong i="8">@components</strong>': path.resolve(__dirname, './src/components'),
      '<strong i="9">@core</strong>': path.resolve(__dirname, './src/core'),
      react: path.resolve(__dirname, './node_modules/react'),
      'react-dom': path.resolve(__dirname, './node_modules/react-dom'),
    },
    extensions: ['.js', '.json', '.tsx', '.ts'],
  },
  externals: {
    react: 'react',
  },
  target: 'node',
  plugins: [
    new HtmlWebPackPlugin({
      template: './tests/index.html',
      filename: 'index.html',
    }),
  ]}

Irgendwelche Vorschläge? Ich habe alle Vorschläge aus alten Diskussionen getestet.
Danke! :Grinsen:

Ich habe eine Settings.js wie folgt deklariert:

import React, {useState} from 'react';

import {
    View,
    Text,
    Switch
} from 'react-native';

export function Settings(props) {
    const [rememberPin, setRememberPin] = useState(false);
    let {changeView, header} = props;


    const toggleRememberPin = (value) => {
        setRememberPin(value);
    };

    return (
            <View>
                    <Text>Remember PIN:</Text>
                    <Switch
                        onValueChange={toggleRememberPin}
                        value={rememberPin}
                        ios_backgroundColor="#aeaeae"
                        />
            </View>
    );
}

export default {Settings};

Ich importiere und verwende es in App.js wie folgt:

import React, {Component} from 'react';
import {
    SafeAreaView,
    StyleSheet,
    View,
    Text,
    TouchableOpacity,
    Dimensions,
    ScrollView,
    Switch
} from 'react-native';

import Colors from './src/assets/Colors';
import {Settings} from './src/components/Settings';
...

export default class App extends Component {
    constructor(props) {
        super(props);
        this.state = {viewsStack: this.viewsStack};
    }

    viewsStack = {
        SplashScreen: false,
        BindingInstructions: false,
        PinPad: false,
        Qr: false,
        Dashboard: false,
        Authorizations: false,
        Settings: true,
        Browsers: false,
        TransmitSDK: false,
        OTP: false,
    };

    changeView = (newView) => {
        let {viewsStack} = this.state;
        for (let key of Object.keys(viewsStack)) {
            viewsStack[key] = false;
        }
        viewsStack[newView] = true;
        this.setState(viewsStack);
    };

    render() {
        let {viewsStack} = this.state;
        return (
            <SafeAreaView style={styles.safeAreaView}>
                {viewsStack.SplashScreen && (splashScreen())}
                {viewsStack.BindingInstructions && (bindingInstructions({changeView: this.changeView}))}
                {viewsStack.PinPad && (pinPad({message: 'Inserisci un nuovo PIN', changeView: this.changeView}))}
                {viewsStack.Qr && (qr({header: 'QR Binding', message: 'Scansiona il QR dalla tua dashboard\noppure\ninserisci il codice manualmente.', changeView: this.changeView}))}
                {viewsStack.Dashboard && (dashboard({header: 'Profilo Utente', changeView: this.changeView}))}
                {viewsStack.Authorizations && (authorizations({header: 'Autorizzazioni', authorizations: [1, 2, 3, 4, 5, 6], changeView: this.changeView}))}
                {viewsStack.Settings && (Settings({header: 'Impostazioni', changeView: this.changeView}))}
            </SafeAreaView>
        );
    }
};
...

Aber ich bekomme:

Screenshot 2020-02-27 at 22 27 01

Ich benutze:

"react": "16.9.0",
"react-native": "0.61.5"

Was ist falsch?

Sie rufen Ihre Settings -Komponente als Funktion und nicht als Funktionskomponente auf.

<Settings header='Impostazioni' changeView={this.changeView} />

Hooks sind in einfachen Funktionen nicht erlaubt, nur in Funktionskomponenten und die Art und Weise, wie Sie es nennen, bringt React dazu, zu denken, dass Ihre Komponente in Wirklichkeit eine normale Funktion ist.

Vielleicht erspart dies jemandem die Kopfschmerzen, wenn Sie React-Router-Dom verwenden, wenn Sie Ihre Komponente so in Render übergeben (nicht der richtige Weg), wird es Invalid Hook Call Warning geben
<Route path="/:cuid/:title" render={PostArticle} />

Ich brauchte eine halbe Stunde, um zu wissen, wo ich falsch gelaufen bin

Dies kann jemandem helfen - wenn dieser Fehler nach der Verwendung von "react-router-dom" auftritt, überprüfen Sie, wie Sie Ihre Routen definiert haben. zB sollte es <Route path={'/upgrade/:plan'} exact children={<Upgrade />} /> sein, während ich <Route path={'/upgrade/:plan'} exact children={Upgrade} /> machte

Dies ist besonders umständlich, wenn Sie Tinte oder Pastell verwenden, um eine CLI zu erstellen (siehe https://github.com/vadimdemedes/pastel/issues/2). Ich kann es nicht zu einem peerDep machen, weil ich nicht jeden Benutzer auffordern kann, React zu installieren, und ich kann sie auch nicht zwingen, eine bestimmte Version / einen bestimmten Bereich von React zu verwenden.

Mein Team verwendet Yarn und erhielt den Invalid hook call -Fehler nur in den Tests, nicht in der App. Das Problem war, dass react-test-renderer auf eine niedrigere Version als react und react-dom aufgelöst wurde, also haben wir resolutions in package.json hinzugefügt:

"devDependencies": {
    ...
    "react": "16.12.0",
    "react-dom": "16.12.0",
    ...
},
"resolutions": {
    "react-test-renderer": "16.12.0"
}

Für Leute, die Gatsby in einem Unterverzeichnis verwenden, ist dies eine mögliche Lösung.

gatsby-node.js :

const path = require('path')
const fromRoot = name => path.resolve(__dirname + '/../node_modules/' + name)

exports.onCreateWebpackConfig = ({ actions }) => actions.setWebpackConfig({
  resolve: {
    alias: {
      'react': fromRoot('react'),
      'react-dom': fromRoot('react-dom'),
    },
  },
})

Ich habe das gleiche Problem, wenn ich den Befehl npm link ausführe, es gibt ein Problem

Dann habe ich die offizielle Lösung von React verwendet, um dieses Problem zu lösen

Dieses Problem kann auch auftreten, wenn Sie npm link oder ein Äquivalent verwenden. In diesem Fall „sieht“ Ihr Bundler möglicherweise zwei Reacts – einen im Anwendungsordner und einen in Ihrem Bibliotheksordner. Unter der Annahme, dass myapp und mylib gleichgeordnete Ordner sind, besteht eine mögliche Lösung darin, npm link ../myapp/node_modules/react von mylib auszuführen. Dadurch sollte die Bibliothek die React-Kopie der Anwendung verwenden.

Wenn A B vorstellen muss (A und B sind Geschwister)

  • Schritt 1 (in B)

    • npm link ./../A/node_modules/react

    • npm link

  • Schritt 2 (in A)
    npm link B

Für mich geht das

Trotz dieser Antworten bin ich mir nicht sicher, warum ich den Fehler bekomme. Ich habe meine Abhängigkeitsbibliothek mit meiner Haupt-App verknüpft, und nachdem ich den Fehler erhalten hatte, folgte ich den React-Dokumenten und verknüpfte die Version von React meiner Abhängigkeitsbibliothek mit der Reaktion meiner App (mit npm link <>/webapp/node_modules/react . (Sogar mit React- true ). Obwohl die Testprotokollierung anzeigte, dass ich keine doppelte Version von React hatte, erhielt ich immer noch den Hook-Fehler.

Aber der Versuch, diese Lösung wie oben erwähnt zu versuchen, hat diesen bestimmten Fehler behoben:

alias: {
        react: path.resolve('./node_modules/react')
 }

Also bin ich ratlos.

Also bin ich ratlos.

@orpheus Rendern Sie mehr als einen einzelnen Reaktionsstamm auf derselben Seite? aka Haben Sie mehr als einen ReactDOM.render Anruf auf derselben Seite?

Rendern Sie mehr als einen einzelnen Reaktionsstamm auf derselben Seite? aka Haben Sie mehr als einen ReactDOM.render Anruf auf derselben Seite?

@Timkindberg

Ich tu nicht. Ich habe mein ReactDOM.render im Stammverzeichnis meines app , und das Modul lib , das ich verlinke, ist eine Komponentenbibliothek und verwendet kein ReactDOM.render überhaupt.

edit: Ich mache so etwas wie:

import React from 'react'
import ReactDOM from 'react-dom'
import Root from './App/Root'

ReactDOM.render(
  <Root />,
  document.getElementById('root')
)

wo <Root /> etwas wie macht

const Root = () => {
  return <Provider store={store}>
        <PermissionsProvider>
              <Suspense fallback={null}>
                <Router history={history}>
                  <Routes store={store} />
                </Router>
              </Suspense>
        </PermissionsProvider>
  </Provider>
}

PermissionsProvider ist die React-Komponente, die ich aus meinem verknüpften lib -Modul importiere, das einen Hook verwendet, der dazu führt, dass die App fehlschlägt. Es erstellt Zustand und Kontext und rendert seine Kinder.

Hallo, ich benutze Elektron mit Reaktionshaken. Wenn ich meinen eigenen Hook schreibe, funktioniert es. Aber es wird ein Fehler ausgegeben, wenn ich Hooks aus anderen Paketen in node_module verwende, wie react-use , swr .

Ich muss das Paket in meine lokale Datei kopieren.

Kennt jemand dieses Problem?

Beispielprojekt hier:
https://github.com/Zaynex/electron-react-ts-kit/tree/hooks-error

Kerncode:
https://github.com/Zaynex/electron-react-ts-kit/blob/hooks-error/src/renderer/app.tsx

Ich habe dieses Problem auch nach dem Entfernen von Duplikaten von „react“ und „react-dom“. Ich habe ein supereinfaches Testprojekt zum Reproduzieren erstellt.

$ tree -I node_modules
.
|-- test-app
|   |-- dist
|   |   |-- index.html
|   |   `-- main.js
|   |-- package-lock.json
|   |-- package.json
|   |-- src
|   |   |-- index.html
|   |   `-- index.js
|   `-- webpack.config.js
`-- test-lib
    |-- dist
    |   `-- main.js
    |-- package-lock.json
    |-- package.json
    |-- src
    |   `-- index.js
    `-- webpack.config.js

Derzeit verwende ich die Webpack-Alias-Methode, aber ich habe auch die npm link -Methode ausprobiert, und beide funktionieren nicht.

Ich bin auch auf dieses Problem gestoßen. Ich verwende ExpressJS + Pug, um Ansichten zu rendern. Ich habe dann einen Renderer (ähnlich wie ReactRails) geschrieben, mit dem Sie Komponenten server- und clientseitig rendern können.

Ich habe versucht, dies in ein separates Paket zu extrahieren, da es unordentlich wurde, und ich bin auf dieses Problem gestoßen.

Um das Problem zu beheben, musste ich unter der Taste resolve hinzufügen:

alias: {
  react: path.resolve("./node_modules/react"),
},

Es funktioniert jetzt wie erwartet, wenn Webpack normal ausgeführt wird, aber das Problem besteht weiterhin mit einem Docker-Volume. Ich bin zu neu für Docker, um mich damit zu befassen, also werde ich es später noch einmal besuchen.

Edit: Ich habe zu früh gesprochen. Es funktioniert jetzt gut mit React Render, aber nicht mit Hydrate.

Hallo, ich benutze Elektron mit Reaktionshaken. Wenn ich meinen eigenen Hook schreibe, funktioniert es. Aber es wird ein Fehler ausgegeben, wenn ich Hooks aus anderen Paketen in node_module verwende, wie react-use , swr .

Ich muss das Paket in meine lokale Datei kopieren.

Kennt jemand dieses Problem?

Beispielprojekt hier:
https://github.com/Zaynex/electron-react-ts-kit/tree/hooks-error

Kerncode:
https://github.com/Zaynex/electron-react-ts-kit/blob/hooks-error/src/renderer/app.tsx

Hallo. Ich hatte das gleiche Problem. Ich verwende Electron-Webpack, das alle Module als Externals für Webpack markiert. Mit wenigen hartcodierten Ausnahmen - wie React und React-Dom.
Für mich bedeutete das, dass die von meinem Code geladene Reaktion anders war als die von einem solchen Modul geladene Reaktion.
Das Hinzufügen dieser Module zur Whitelist scheint zu helfen (nicht sicher, ob es noch nichts kaputt gemacht hat :)

@huhle danke, es funktioniert! Vielleicht sollten wir in das Elektron-Webpack eintauchen.

Ich habe es gerade geschafft, das selbst zum Laufen zu bringen. Ich denke, es ist eine der besseren Lösungen, wenn es um Lerna- und Yarn-Arbeitsbereiche geht, und vielleicht könnten einige der Teile für eine andere Lösung verwendet werden.

Es scheint alles auf die Konfiguration des package.json -Projekts hinauszulaufen, das ich importiere. Ich musste diese Abschnitte einfügen:

 "peerDependencies": {
    "react": "^16.13.1",
    "react-dom": "^16.13.1"
  },
  "workspaces": {
    "nohoist": [
      "react", "react-dom"
    ]
  }

Danach musste ich die Projekte neu erstellen und ich war einsatzbereit. Es scheint, dass die Auflistung als Peer-Abhängigkeiten es ermöglicht, dass sie von Ihrem verbrauchenden Projekt installiert werden müssen. Und weil sie nicht in den Abhängigkeiten aufgeführt sind, sollten sie für das Paket, das Sie zu importieren versuchen, nicht verfügbar sein, aber aus irgendeinem Grund bleiben sie verfügbar, es sei denn, Sie sagen ihm, dass es nicht gehisst werden soll, und eine neue React-Instanz findet ihren Weg in und verursacht den Fehler.

Viel Glück!

Ich versuche, React-Spring zu verwenden, um einen einfachen Einblendeffekt zu erzielen. Nichts scheint zu funktionieren.
`import React, {useState, useEffect} from 'react';
import {animation, useTransition} from 'react-spring';

const TextContent = (Requisiten) => {

const [items] = useState([
    { id: '0', title: 'Text1' },
    { id: '1', title: 'Text2' },
    { id: '2', title: 'Text1' }
])

const [index, setIndex] = useState(0);

const transitions = useTransition(items[index], index => index.id,
    {
        from: { opacity: 0 },
        enter: { opacity: 1 },
        leave: { opacity: 0 },
        config: { tension: 220, friction: 120 }
    }
)

useEffect(() => {
    const interval = setInterval(() => {
        setIndex((state) => (state + 1) % items.length);
    }, 4000)
    return () => clearInterval(interval);
}, []);

return (
    <div>
        {
            transitions.map(({ item, props, key }) => (
                <animated.div
                    key={key}
                    style={{ ...props, position: 'absolute' }}
                >
                    <p>{item.title}</p>
                </animated.div>
            ))
        }
    </div>
)

}

export default TextContent;`
Capture

Ich habe versucht zu überprüfen, ob ich mehrere Instanzen von React habe. Npm ls-ing sagt mir, dass ich nur eine einzige Version von „react“ und „react-dom“ habe, beide am 16.13.1.

Hallo, ich benutze Elektron mit Reaktionshaken. Wenn ich meinen eigenen Hook schreibe, funktioniert es. Aber es wird ein Fehler ausgegeben, wenn ich Hooks aus anderen Paketen in node_module verwende, wie react-use , swr .
Ich muss das Paket in meine lokale Datei kopieren.
Kennt jemand dieses Problem?
Beispielprojekt hier:
https://github.com/Zaynex/electron-react-ts-kit/tree/hooks-error
Kerncode:
https://github.com/Zaynex/electron-react-ts-kit/blob/hooks-error/src/renderer/app.tsx

Hallo. Ich hatte das gleiche Problem. Ich verwende Electron-Webpack, das alle Module als Externals für Webpack markiert. Mit wenigen hartcodierten Ausnahmen - wie React und React-Dom.
Für mich bedeutete das, dass die von meinem Code geladene Reaktion anders war als die von einem solchen Modul geladene Reaktion.
Das Hinzufügen dieser Module zur Whitelist scheint zu helfen (nicht sicher, ob es noch nichts kaputt gemacht hat :)

Brillant! Danke

Ich versuche, React-Spring zu verwenden, um einen einfachen Einblendeffekt zu erzielen. Nichts scheint zu funktionieren.
`import React, {useState, useEffect} from 'react';
import {animation, useTransition} from 'react-spring';

const TextContent = (Requisiten) => {

const [items] = useState([
    { id: '0', title: 'Text1' },
    { id: '1', title: 'Text2' },
    { id: '2', title: 'Text1' }
])

const [index, setIndex] = useState(0);

const transitions = useTransition(items[index], index => index.id,
    {
        from: { opacity: 0 },
        enter: { opacity: 1 },
        leave: { opacity: 0 },
        config: { tension: 220, friction: 120 }
    }
)

useEffect(() => {
    const interval = setInterval(() => {
        setIndex((state) => (state + 1) % items.length);
    }, 4000)
    return () => clearInterval(interval);
}, []);

return (
    <div>
        {
            transitions.map(({ item, props, key }) => (
                <animated.div
                    key={key}
                    style={{ ...props, position: 'absolute' }}
                >
                    <p>{item.title}</p>
                </animated.div>
            ))
        }
    </div>
)

}

export default TextContent;`
Capture

Ich habe versucht zu überprüfen, ob ich mehrere Instanzen von React habe. Npm ls-ing sagt mir, dass ich nur eine einzige Version von „react“ und „react-dom“ habe, beide am 16.13.1.

Hier gilt das gleiche. React und React-Dom sind für mich auf 16.13.1, und der Versuch, React-Spring zu verwenden, bringt denselben Fehler.

Aus einem anderen Thread bei styled-components habe ich gelernt, dass Sie $#$3$ verwenden müssen, wenn Sie ein eigenes lokales Paket über eine file: URI in package.json rm -rf node_modules/local-package-name/node_modules verwenden node_modules auf redundante Abhängigkeiten zu prüfen.

Aus einem anderen Thread bei styled-components habe ich gelernt, dass Sie $#$3$ verwenden müssen, wenn Sie ein eigenes lokales Paket über eine file: URI in package.json rm -rf node_modules/local-package-name/node_modules verwenden node_modules auf redundante Abhängigkeiten zu prüfen.

Ja, das ist das gleiche Problem für ungefähr ein Dutzend Anwendungsfälle allein in diesem Thread. Ich habe ein „prestart“- und „prebuild“-Ziel hinzugefügt, um rm -rf (mit rimraf) auszuführen. Ein anderer Benutzer in diesem Thread verwendete npm-link-shared in seinem Prestart, um die Module dazu zu bringen, dieselbe Instanz von React zu teilen. So viele von uns Monorepo-Benutzern stoßen darauf.

Hallo, ich benutze Elektron mit Reaktionshaken. Wenn ich meinen eigenen Hook schreibe, funktioniert es. Aber es wird ein Fehler ausgegeben, wenn ich Hooks aus anderen Paketen in node_module verwende, wie react-use , swr .
Ich muss das Paket in meine lokale Datei kopieren.
Kennt jemand dieses Problem?
Beispielprojekt hier:
https://github.com/Zaynex/electron-react-ts-kit/tree/hooks-error
Kerncode:
https://github.com/Zaynex/electron-react-ts-kit/blob/hooks-error/src/renderer/app.tsx

Hallo. Ich hatte das gleiche Problem. Ich verwende Electron-Webpack, das alle Module als Externals für Webpack markiert. Mit wenigen hartcodierten Ausnahmen - wie React und React-Dom.
Für mich bedeutete das, dass die von meinem Code geladene Reaktion anders war als die von einem solchen Modul geladene Reaktion.
Das Hinzufügen dieser Module zur Whitelist scheint zu helfen (nicht sicher, ob es noch nichts kaputt gemacht hat :)

Dies gilt auch für Leute, die Probleme mit Redux oder Redux Toolkit und Electron-Webpack haben. Ich habe folgende funktionierende Konfiguration:

// package.json
...
"electronWebpack": {
  "whiteListedModules": ["react-redux"]
}

siehe https://github.com/electron-userland/electron-webpack/issues/349

Mein Problem war, dass ich geschrieben habe

import React from 'React'

Anstatt:

import React from 'react'

Manchmal sind es die dummen Dinger.

Ich habe es gelöst, indem ich meiner Webpack-Konfiguration Folgendes hinzugefügt habe:

 externals: {
    react: {
      root: "React",
      commonjs2: "react",
      commonjs: "react",
      amd: "react",
    },
    "react-dom": {
      root: "ReactDOM",
      commonjs2: "react-dom",
      commonjs: "react-dom",
      amd: "react-dom",
    },
  },

Ich dachte zunächst, es sei ein Problem mit npm link, tat alles, was vorgeschlagen wurde, und wechselte sogar zu Garn. Schließlich stellte sich heraus, dass beim Veröffentlichen in npm beim Importieren in ein anderes Projekt derselbe Fehler aufgetreten war.

Hat das hier kürzlich jemand mit einem lerna monorepo gelöst? Ich habe ein paar der Vorschläge ohne Erfolg ausprobiert.

Nach dem Hinzufügen des Codes, der unten mit // auskommentiert ist, tritt der Fehler auf. Das Hinzufügen der CssBaseline- und Reaktionsfragmentinformationen verursacht den Fehler. Alles läuft gut, wenn es auskommentiert ist. Der ursprüngliche Code ist einfach der grundlegende npx create-react-app-Code. Völlig neu und einige der Korrekturen, die ich von oben ausprobiert habe, hatten keine Wirkung.

Reagieren von 'Reagieren' importieren;
Logo aus „./logo.svg“ importieren;
CssBaseline aus „@material-ui/core/CssBaseline“ importieren;

Standardfunktion exportieren App() {
Rückkehr (

        //<React.Fragment>

        //<CssBaseline />

        <div className="App">
            <header className="App-header">
                <img src={logo} className="App-logo" alt="logo" />
                <p>
                    Edit <code>src/App.js</code> and save to reload.
                    </p>
                <a
                    className="App-link"
                    href="https://reactjs.org"
                    target="_blank"
                    rel="noopener noreferrer"
                >
                    Learn React
                    </a>
            </header>
        </div>

    //</React.Fragment>

);
}

Für lokale Tests:
Löschen Sie in der Bibliothek node_modules den Ordner „react“ und „react-dom“.
Führen Sie im Hauptpaket erneut "yarn install" oder "npm install" aus.

Dadurch wird verhindert, dass die zweite Kopie von React in das Hauptbündel geladen wird. Offensichtlich keine dauerhafte Lösung, aber für lokale Tests geeignet.

Für alle, die Lerna verwenden, können Sie auf dieses Problem stoßen, wenn Sie Tests in einem Paket ausführen, bei denen der Code auf Komponenten in einem anderen Paket verweist.

Das Problem, das wir in diesem Fall hatten, war darauf zurückzuführen, dass die Reaktion in die Spezifikation importiert wurde und auch in eine Komponente im Komponentenbaum importiert wurde, die withStyles der Material-Benutzeroberfläche verwendete , die mithilfe von Hooks in der Material-Benutzeroberfläche implementiert wurde.

Es scheint, dass React intern den Zustand in einer ReactCurrentDispatcher.current -Variablen verwaltet, und dies endet damit, dass es in einer Instanz von React gesetzt, aber in der anderen Instanz von React verwendet wird – wenn es leer ist, wirft es das Invalid hook call ... Nachricht.

Wir haben Craco bereits verwendet, um die Webpack-Konfiguration von Create React App zur Erstellungszeit zu überschreiben:

  webpack: {
    alias: {
      react: path.resolve(__dirname, './node_modules/react'),
    },
  },

Diese Webpack-Überschreibung wird jedoch nur zur Erstellungszeit verwendet – beim Ausführen der Tests wird der Code nicht erstellt, sondern aus der Quelle instanziiert – daher bestand unsere Lösung darin, CracoAlias ​​in unserem craco.config.js zu verwenden, um es anzugeben der Reaktionsweg während der Tests:

  plugins: [
    {
      plugin: CracoAlias,
      options: {
        source: 'options',
        baseUrl: './',
        aliases: {
          // We need to alias react to the one installed in the desktop/node_modules
          // in order to solve the error "hooks can only be called inside the body of a function component"
          // which is encountered during desktop jest unit tests,
          // described at https://github.com/facebook/react/issues/13991
          // This is caused by two different instances of react being loaded:
          // * the first at packages/desktop/node_modules (for HostSignUpDownloadComponent.spec.js)
          // * the second at packages/components/node_modules (for packages/components/Modal)
          react: './node_modules/react',
        },
      },
    },
  ],

Ich habe @craco/craco als Lösung verwendet, ohne auszuwerfen, nach dem Beispiel von @apieceofbart . Die Schritte für mich waren die folgenden mit npm link , um das lokale Modul zu testen:

  1. Installieren Sie craco in meiner Demo-App, indem Sie npm i @craco/craco --save ausführen
  2. Erstellen Sie die Konfigurationsdatei craco.config.js , um dort zu rooten, wo sich package.json in der Demo-App befindet.
  3. Ändern Sie die Skripte start , build und test , indem Sie in meiner Demo-App react-scripts durch craco ersetzen.
// craco.config.js
const path = require('path');

module.exports = {
    webpack: {
        alias: {
            react: path.resolve(__dirname, './node_modules/react')
        }
    }
}
// package.json
{
....
"scripts": {
    "start": "craco start",
    "build": "craco build",
    "test": "craco test",
    "eject": "react-scripts eject"
  },
...
}

edit: Ich habe nicht einmal bemerkt, dass @jasondarwin die gleiche Idee hatte.

Ich habe fast einen Tag damit verbracht, dieses Problem zu beheben. Poste meine Lösung hier, falls es jemandem hilft.

Wir verwenden ein Monorepo und zwei Pakete importierten unterschiedliche Instanzen von React, aber sie wurden an derselben Stelle in den Root-Node-Modulen aufgelöst. Es stellte sich heraus, dass wir diese beiden Instanzen hatten, weil eine der Apps ihr eigenes Webpack verwendet hat, um ein Bundle zu erstellen. Dies wurde korrekterweise zum Root-Node-Modul gehisst, erhielt aber eine eigene Instanz, wenn es von diesem Paket importiert wurde. Die Lösung bestand darin, „react“ und „react DOM“ in die Externals der Webpack-Konfiguration aufzunehmen, sodass „webpack“ keine neue Instanz von „react“ für das Bundle erstellen würde.

externals: { react: 'react', reactDOM: 'react-dom', },

Hoffe das hilft jemandem!

Für mich wurde die Version 4.0.0 des React-Hot-Loaders verwendet, die Aktualisierung auf React-Hot-Loader 4.8 scheint den Zweck zu erfüllen

Ich erhalte die Invalid hook call -Nachricht NUR , wenn ich meine Tests auf einem benutzerdefinierten Hook ausführe, den ich für die Arbeit mit modalen Fenstern erstelle.

Um das Verhalten zu demonstrieren, habe ich im Folgenden ein Beispiel erstellt:
(https://github.com/BradCandell/invalid-hook-example)

  • Nur eine Version von react und react-dom

Übersehe ich etwas schrecklich Offensichtliches? Wenn ich in der Vergangenheit gegen die Regel verstoßen habe, ist npm start fehlgeschlagen. Aber das versagt nur in meinen Tests.

Ich weiß die Hilfe zu schätzen!
-Brad

Ich habe es gelöst, indem ich meiner Webpack-Konfiguration Folgendes hinzugefügt habe:

 externals: {
    react: {
      root: "React",
      commonjs2: "react",
      commonjs: "react",
      amd: "react",
    },
    "react-dom": {
      root: "ReactDOM",
      commonjs2: "react-dom",
      commonjs: "react-dom",
      amd: "react-dom",
    },
  },

Ich dachte zunächst, es sei ein Problem mit npm link, tat alles, was vorgeschlagen wurde, und wechselte sogar zu Garn. Schließlich stellte sich heraus, dass beim Veröffentlichen in npm beim Importieren in ein anderes Projekt derselbe Fehler aufgetreten war.

Dies hat es für mich behoben. Ich importierte React-Toastify und bekam den ungültigen Hook-Call. Ich bin jedes Element im Konsolenfehler durchgegangen:

  1. Möglicherweise haben Sie nicht übereinstimmende Versionen von React und React DOM.

    1. Sie könnten die Hook-Regeln brechen.

    2. Möglicherweise haben Sie mehr als eine Kopie von React in derselben App.

War am Ende die 3. Ausgabe. Ich habe folgendes befolgt:
https://reactjs.org/warnings/invalid-hook-call-warning.html#duplicate -react

Keine der oben genannten Lösungen funktionierte für mich, bis mir klar wurde, dass ich eine weitere Kopie von React mit der Bibliothek bündelte, die ich _importierte_.
Ich hatte den Quellcode meiner Bibliothek transpiliert und gebündelt, sodass die Suche nach verschiedenen Versionen von React, die in den Dokumenten aufgeführt sind, true anstelle von false zurückgab.
Das Markieren react als externe Abhängigkeit und das Weglassen aus dem Bündel meiner Bibliothek hat den Zweck erfüllt.

Mein Fall war kein Monorepo, aber eine ähnliche Situation. Wir entwickeln ein neues UI-Framework, und anstatt npm link oder lerna zu verwenden, verwenden wir einfach Webpack-Aliase, um die Dateien in einem gleichgeordneten Ordner anzufordern. Es funktioniert gut, aber Sie werden auf dieses Problem stoßen. Glücklicherweise hat die Lösung von @apieceofbart das Problem für uns behoben.

Zeile 130:21: React Hook „useStyles“ wird in der Funktion „pharmacyDashboard“ aufgerufen, die weder eine React-Funktionskomponente noch eine benutzerdefinierte React-Hook-Funktion „react-hooks/rules-of-hooks“ ist
Zeile 133:45: React Hook „React.useState“ wird in der Funktion „pharmacyDashboard“ aufgerufen, die weder eine React-Funktionskomponente noch eine benutzerdefinierte React-Hook-Funktion „react-hooks/rules-of-hooks“ ist

das ist der Fehler ..... kann mir bitte jemand bei der Lösung dieses Problems helfen

@vyshnaviryali Sie nennen Ihre Funktion besser usePharmacyDashboard

./src/components/HomeFiles/AppFooter.js
Zeile 1:1: Definition für Regel 'material-ui/no-hardcoded-labels'' wurde nicht gefunden material-ui/no-hardcoded-labels'
kann mir bitte jemand bei der Lösung helfen

Für alle, die dieses Problem mit npm link , weil Sie Ihren Komponenten Funktionen hinzufügen müssen, dies aber vor dem Testen nicht npm publish tun möchten, bin ich überrascht, dass niemand vorgeschlagen hat, yalc zu verwenden

Für alle, die dieses Problem mit npm link , weil Sie Ihren Komponenten Funktionen hinzufügen müssen, dies aber vor dem Testen nicht npm publish tun möchten, bin ich überrascht, dass niemand vorgeschlagen hat, yalc zu verwenden

Das habe ich letztes Jahr tatsächlich getan: https://github.com/facebook/react/issues/13991#issuecomment -535150839

Wir benutzen es jetzt seit fast einem Jahr ohne Probleme.

Ein anderer hier mit lerna; Um dies zu beheben, habe ich die Abhängigkeiten react und react-dom in mein Stammverzeichnis package.json verschoben.

Ich hatte das gleiche Problem und habe es gelöst, indem ich hinzugefügt habe:

 alias: {
        react: path.resolve('./node_modules/react')
      }

in die Eigenschaft resolve in der Webpack-Konfiguration meiner Haupt-App.

Es war offensichtlich mein Fehler, zwei Kopien von React zu verwenden, aber ich stimme zu, dass es großartig wäre, wenn die Fehlermeldung besser wäre. Ich denke, das ist vielleicht ähnlich wie: #2402

Für diejenigen, die die obige Methode verwenden, aber immer noch die Fehler beim Ausführen von Jest erhalten, fügen Sie diese zu moduleNameMapper in der Konfiguration von Jest hinzu (lassen Sie "react-dom" weg, wenn es nicht erforderlich ist):

moduleNameMapper: {

...

  "^react$": "<rootDir>/node_modules/react",
  "^react-dom$": "<rootDir>/node_modules/react-dom",

...

}

Ich bin ratlos. Ich bekomme das, aber meine App verwendet keine Hooks und es gibt keine Duplikate von React oder React-Dom. Ich verwende next.js. Kann das was damit zu tun haben?

npm ls react
npm ls react-dom

@maapteh war das für mich? Ich habe diese Befehle ausgeführt und keine Duplikate gefunden. Beide Bibliotheken haben die Version 16.13.1

@dancancro Ich verwende auch Next.js und kann das nicht beheben.

npm ls react und npm ls react-dom geben beide nur einen Eintrag zurück. Aber ich bin mir nicht sicher, ob das richtig ist. Ich stoße auf diesen Fehler, wenn ich ein lokales Paket für die Entwicklung verlinke. npm ls gibt nur einen Eintrag zurück, auch wenn ich die Reaktion in der Abhängigkeit nicht mit dem Hauptrepo verlinke. Aber selbst wenn ich den Link richtig reagiere, bekomme ich immer noch den Fehler.

@justincy Ich habe keine Paketlinks in meinem Projekt. Ich wette, es hängt mit Next.js zusammen. Das Problem verschwindet, wenn ich die Hauptkomponente in ein typeof document !== 'undefined' setze, wodurch der Zweck von Next.js effektiv untergraben wird

Ich habe es geschafft, mein Problem zu beheben, indem ich in der Abhängigkeit „react“ und „react-dom“ aus „node_modules“ gelöscht habe. Es ist nicht ideal, aber zumindest kann ich weiterarbeiten.

@dancancro Ich bin skeptisch, dass Ihr Problem von Next.js verursacht wird. Wenn es so wäre, hätten viele andere das Problem. Ich stoße nur wegen verknüpfter Pakete darauf. Ich sehe den Fehler nicht ohne verknüpfte Pakete.

Das Problem verschwindet, wenn ich fünf der sieben Komponenten in der Hauptkomponente entferne. Ich kann nichts Besonderes an diesen Komponenten erkennen. Das Einschließen dieser Komponenten in typeof document !== 'undefined' s funktioniert ebenfalls.

Hallo Team, ich versuche, die React-Version von 16.2.0 auf 16.13.1 zu aktualisieren, habe dasselbe auch für React-Dom gemacht.
Jetzt habe ich eine Wrapper-Komponente, die bei "/ test" aufgerufen wird.

class TestWrapper extends React.Component { render() { return ( <React.Fragment> <TestComponent /> </React.Fragment> ) } }

im test wrapper habe ich eine funktionale komponente mit einem hook importiert
function TestComponent(props) { useEffect(() => { console.log("TEST COMPONENT"); }); return ( <div> Hello world! </div> ) }

Aber wenn die Seite UseEffect rendert, funktioniert der Hook nicht und es tritt ein Fehler auf, dh eine ungültige Hook-Call-Warnung
PS. :

  1. Ich habe überprüft, dass ich nur eine Kopie von React habe und React-Dom installiert ist
  2. Die React- und React-Dom-Version ist 16.13.1

Das habe ich
Ich habe gerade ...
@ @
ReactError
Ich verwende nextJS, sodass React nicht importiert werden muss. Und ich habe es versucht - nicht helfen.

Alle anderen Seiten und Funktionen funktionieren einwandfrei

@Brotipok welche Version von next.js? (Ich sehe ähnliche Probleme, aber nur beim Umstieg auf 9.5 von 9.4.X)

Hallo!

Ich habe den gleichen Fehler, nur ein Paket für React und React Dom, wenn ich npm ls mache.

Reaktionsversion: 16.13.1
React-Dom-Version: 16.13.1

Ich verwende Typescript und habe das Projekt mit create-react-app my-app --template typescript initialisiert.

Funktionale Komponenten funktionieren nur, wenn ich darin keine Hooks verwende.

Paket.json

{
"name": "blablamovie",
"Version": "0.1.0",
"privat": wahr,
"Abhängigkeiten": {
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.5.0",
"@testing-library/user-event": "^7.2.1",
"@types/jest": "^24.9.1",
"@types/node": "^12.12.53",
"@types/react": "^16.9.43",
"@types/react-dom": "^16.9.8",
"@types/react-router-dom": "^5.1.5",
"react-icons": "^3.10.0",
"Reaktionsskripte": "3.4.1",
"typoskript": "^3.7.5",
"webpack-bundle-analyzer": "^3.8.0"
},
"Skripte": {
"start": "React-Skripte starten",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "React-Skripte auswerfen",
"analyze": "source-map-explorer 'build/static/js/*.js'"
},
"eslintConfig": {
"erweitert": "react-app"
},
"Browserliste": {
"Produktion": [
">0,2 %",
"nicht tot",
"nicht op_mini alle"
],
"Entwicklung": [
"letzte 1 Chrome-Version",
"letzte 1 Firefox-Version",
"letzte 1 Safari-Version"
]
}
}
Es ist ein wichtiges Projekt und es macht mich ein bisschen verrückt.
Wenn jemand helfen kann, wäre es großartig.
Danke.

@Brotipok welche Version von next.js? (Ich sehe ähnliche Probleme, aber nur beim Umstieg auf 9.5 von 9.4.X)

Hier sind Abhängigkeiten
"Abhängigkeiten": {
"weiter": "9.4.4",
"nächste Bilder": "^1.4.0",
"node-sass": "^4.14.1",
"reagieren": "16.13.1",
"react-document-meta": "^3.0.0-beta.2",
"react-dom": "16.13.1",
"react-horizontal-timeline": "^1.5.3",
"react-meta-tags": "^0.7.4",
"react-onclickoutside": "^6.9.0"
},
"devDependencies": {
"@types/node": "^14.0.23",
"@types/react": "^16.9.43",
"typoskript": "^3.9.7"
}

Ich stoße auf dasselbe Problem beim Importieren material-ui/core/Dialog -Komponenten. Ich habe mein package.json so eingestellt, dass es die Reaktion 16.8.0 speziell für react und react-dom verwendet.

Ich habe npm ls react und npm ls react-dom mit nur einem Import ausgeführt. Ich habe auch den auf der Fehlerseite beschriebenen Test ausprobiert:

// Add this in node_modules/react-dom/index.js
window.React1 = require('react');

// Add this in your component file
require('react-dom');
window.React2 = require('react');
console.log(window.React1 === window.React2);

Was false zurückgibt, aber wie würde ich die "andere" Reaktionsversion aufspüren, die von einer Abhängigkeit importiert wird? Dies scheint nur zu passieren, wenn ich die Komponente " Material UI Dialog " importiere, es passiert, sobald ich tippe eine Schaltfläche, die es zum Rendern auslöst. Ich kann andere Komponenten wie List und ListItems usw. verwenden.

Ich habe versucht , Auflösungen zu erzwingen, und es hat es auch nicht behoben.

Ich verwende kein Web Pack (wirklich kleines Projekt), also erfolgt der Build mit react-scripts build , falls das einen Unterschied macht.

Umschreiben: Ich ersetze meine Frage einfach durch eine Lösungsreferenz (und vielleicht eine Bitte um noch mehr Begriffsklarheit in den Dokumenten, für uns Dummies? :) )

Hintergrund:
Ich habe versucht, eine funktionale Komponente mit Hooks in ein Asset zu webpack-kompilieren, wo diese Komponente von Vanilla JS im Browser aufgerufen werden konnte.

Zum Beispiel,

function Example() {
    const [count, setCount] = React.useState(0);

    return <button onClick={() => setCount(count + 1)}>
        You clicked {count} times
    </button>;
}
export default Example;

... die ich als eigenständiges Modul exportieren wollte, und nach dem Laden dieses Assets direkt aus HTML verwenden, ähnlich wie:

<script defer>
            ReactDOM.render(
                ExportedCompiledExample.default(props),
                document.getElementById("my_element")
            );
</script>

Ich habe das vor langer Zeit zum Laufen gebracht _solange die Komponente keine Hooks enthielt_. Aber bei der Verwendung von Hooks stieß ich immer wieder auf diese gefürchtete Fehlermeldung.

Die tischumdrehend einfache Lösung
Ich bin _vielen_ komplizierteren Ablenkungsmanövern gefolgt (mehrere React/ReactDOM-Versionen/Instanzen, npm-Importe und versteckte sekundäre Abhängigkeiten, React-Hot-Loader, Webpack-Setup, Externe, unterschiedliche Bundle-/Modul-/Bibliothekskonventionen, Post-Compilation-Struktur.. .) bevor Sie dies versuchten, was funktionierte:

export default () => <Example />;

(oder gegebenenfalls export default props => <Example {...props} /> ).

Im Rückblick 20/20 macht es Sinn, denke ich.

Aber nur um die Quelle der Verwirrung zu lokalisieren, falls jemand anderes sie braucht: Die Rules-of-Hooks-Dokumentation sagt _Call them at the top level in the body of a function component_. Was ich dachte, ich hätte es getan, da ich das Beispiel tatsächlich direkt in meine Struktur eingefügt habe.

Meine Interpretation ist, dass dies aus den Beispielen ...

function Example() {
  // Declare a new state variable, which we'll call "count"
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

... ist KEIN Funktionsbaustein an sich? Im richtigen Aufrufkontext wird es so (also nicht Example() sondern <Example /> ).

Ich glaube, ich habe es woanders in den Dokumenten übersehen, aber falls nicht: Es hätte mir viel Zeit gespart, wenn ein bisschen Nutzungskontext (oder nur ein ES-Modul-Setup) enthalten/erwähnt/verlinkt worden wäre. :) Zumal die direkte export default Example Version ohne Hooks funktioniert.

Danke für eine funktionierende Lösung @apieceofbart! Mein Problem bezog sich auf den npm-Link.

So habe ich es mit Create React App zum Laufen gebracht, wo die Webpack-Konfiguration per Design ausgeblendet ist. Es könnte auch deine Lösung sein @florianzemma?

  1. npm install -D react-app-rewired
  2. Erstellen Sie eine Datei mit dem Namen config-overrides.js in Ihrem Projektstammverzeichnis.
// config-overrides.js
module.exports = function override(config, env) {
  const path = require('path');

  return {
    ...config,
    resolve: {
      ...config.resolve,
      alias: {
        ...config.resolve.alias,
        react: path.resolve('./node_modules/react')
      }
    }
  };
}
  1. Ersetzen Sie relevante react-scripts ... -Befehle in package.json durch react-app-rewired ... .

Ich hoffe, es hilft

Ich habe diesen Fehler erhalten, weil ich die Bundles 2 Mal geladen habe.
In meinem Fall ist es passiert, weil die Nunjucks-Vorlage, in der Skript-Tags gerendert wurden, zweimal verwendet wurde - im Layout selbst und im Allgemeinen als Vorlage für Head-Tag-Inhalte.

Problemumgehung für Garn

Ich verwende Yarn und habe dies behoben, indem ich die Auflösung in meinem package.json habe:

  "resolutions": {
    "**/react": "16.7.0-alpha.2",
    "**/react-dom": "16.7.0-alpha.2"
  },

Neben dem Hinzufügen der Auflösung in der übergeordneten App (verbrauchende Bibliothek) habe ich die Bibliotheksabhängigkeiten mit den folgenden Befehlen aktualisiert:

  1. yarn add link:/path/to/parent-app/node_modules/react
  2. yarn add link:/path/to/parent-app/node_modules/react-dom

Danach habe ich die Bibliothek in der übergeordneten App mit yarn add link:/path/to/library neu verknüpft

Hallo
Ich stoße auf das gleiche Problem mit Garn-Arbeitsbereichen.
Ich habe so ein Layout:

Arbeitsplatz/
├── Bibliothek/
├── app1/
├── app2/

app1 und app2 haben direkte Abhängigkeiten zu React v16.9.0, React-dom v16.9.0 und 'library'.
„Bibliothek“ hat eine Peer-Abhängigkeit, um v16.9.0 zu reagieren, aber auch eine Entwickler-Abhängigkeit von Storybook.
Das Problem scheint von Storybook zu stammen, das eine Abhängigkeit von React v16.13.1 hat.
Wenn ich jedoch die Garninstallation ausführe, lande ich mit der Reaktion 16.13.1 in meinen Knotenmodulen der obersten Ebene und der Reaktion 16.9.0 in den lokalen Knotenmodulen von app1 und app2.

Wenn ich app1 (erstellt mit CRA) ausführe, verwendet es sein lokales React v16.9.0, aber die Komponenten aus „library“ verwenden React v16.13.1

Dies scheint mir ein Problem mit der Garnhebelogik, der Webpack-Definition von create-react-apps oder beidem zu sein?
Hat jemand eine Idee für einen Workaround für dieses Szenario?

Hallo
Ich stoße auf das gleiche Problem mit Garn-Arbeitsbereichen.
Ich habe so ein Layout:

Arbeitsplatz/
├── Bibliothek/
├── app1/
├── app2/

app1 und app2 haben direkte Abhängigkeiten zu React v16.9.0, React-dom v16.9.0 und 'library'.
„Bibliothek“ hat eine Peer-Abhängigkeit, um v16.9.0 zu reagieren, aber auch eine Entwickler-Abhängigkeit von Storybook.
Das Problem scheint von Storybook zu stammen, das eine Abhängigkeit von React v16.13.1 hat.
Wenn ich jedoch die Garninstallation ausführe, lande ich mit der Reaktion 16.13.1 in meinen Knotenmodulen der obersten Ebene und der Reaktion 16.9.0 in den lokalen Knotenmodulen von app1 und app2.

Wenn ich app1 (erstellt mit CRA) ausführe, verwendet es sein lokales React v16.9.0, aber die Komponenten aus „library“ verwenden React v16.13.1

Dies scheint mir ein Problem mit der Garnhebelogik, der Webpack-Definition von create-react-apps oder beidem zu sein?
Hat jemand eine Idee für einen Workaround für dieses Szenario?

Die einzige Lösung, die ich dafür gefunden habe, war die CRA-App yarn run eject und die Reihenfolge des Abschnitts resolve zu ändern von:

``` Javascript
Module: ['node_modules', path.appNodeModules].concat(
module.additionalModulePaths || []
),
````

zu
``` Javascript
Module: [paths.appNodeModules, 'node_modules'].concat(
module.additionalModulePaths || []
),
````

Es erscheint mir seltsam, dass die 'appNodeModules' nicht die höchste Priorität haben - sicherlich sollte die eigentliche fragliche App zurückgestellt werden, wenn es darum geht, Abhängigkeiten aufzulösen?

Ich bin auf das „Hooks“-Problem in einer Umgebung mit Webpack und Electron gestoßen. Mein Projekt hat eine Abhängigkeit von einem Modul A, das selbst von Webpack gebündelt ist (und das ich selbst verfasst habe). Ich habe React von A externalisiert (und es als commonjs2-Modul deklariert). Dies schließt die React-Dateien aus dem Bibliothekspaket aus.

Mein Hauptprogramm, das im Electron Renderer-Prozess läuft, verwendet ebenfalls React. Ich ließ Webpack React in das Bundle aufnehmen (keine spezielle Konfiguration).

Dies führte jedoch zu dem „Hooks“-Problem aufgrund von zwei Instanzen von React in der Laufzeitumgebung.

Dies wird durch diese Tatsachen verursacht:

  • Modul A „erfordert“ Reagieren und dies wird durch das Modulsystem von Electron gelöst. Also nimmt Electron React von node_modules;
  • das Hauptprogramm verlässt sich auf die Webpack-Laufzeitumgebung, um React aus dem Paket selbst zu „laden“.
  • Sowohl Electron als auch die Webpack-Laufzeit haben ihren eigenen Modul-Cache ...

Meine Lösung bestand darin, React auch aus dem Hauptprogramm zu externalisieren. Auf diese Weise erhalten sowohl das Hauptprogramm als auch Modul A ihren React von Electron – eine einzelne Instanz im Speicher.

Ich habe eine beliebige Anzahl von Aliasen ausprobiert, aber das löst das Problem nicht, da ein Alias ​​Webpack nur anweist, wo der Modulcode zu finden ist. Es ändert nichts an der Problematik mehrerer Modul-Caches!

Wenn Sie auf dieses Problem mit einem Modul stoßen, das Sie nicht steuern können, finden Sie heraus, ob und wie React externalisiert wird. Wenn es nicht externalisiert wird, denke ich, dass Sie dieses Problem im Kontext von Electron nicht lösen können. Wenn es nur als global externalisiert wird, fügen Sie React in Ihre .html-Datei ein und machen Sie Ihr Hauptprogramm auch davon abhängig.

Endlich...

//webpack.config.js

module.exports = {
  ...
  externals: {
      react: 'react',
  },
}

Vue3 hat das gleiche Problem

Ich habe dieses Problem gelöst, indem ich react und react-dom als peerDependencies in meine package.json meiner externen Bibliothek eingefügt habe, die React verwendet.

  "peerDependencies": {
    "react": "^16.13.1",
    "react-dom": "^16.13.1"
  },

Ich glaube, ich habe es woanders in den Dokumenten übersehen, aber falls nicht: Es hätte mir viel Zeit gespart, wenn ein bisschen Nutzungskontext (oder nur ein ES-Modul-Setup) enthalten/erwähnt/verlinkt worden wäre. :) Zumal die direkte export default Example Version ohne Hooks funktioniert.

Hallo @espen42 ,
Ich hatte wirklich gehofft, dass Ihre Lösung uns helfen wird. Wir haben buchstäblich _alles_ ausprobiert, genau wie du es erwähnt hast.

Leider scheint auch deine Lösung nicht zu helfen. Ich frage mich, ob ich vielleicht nur etwas übersehen habe?

In einem Paket (ich nenne es @bla/bla) haben wir also das index.js , das eine Komponente mit Hooks hat, wie z

function Bla = ({...props]) => {
const [bla, setBla] = useState(false);
return bla ? <div {...props} /> : 'no luck';
}

Wir kompilieren das Paket mit npx babel .

Wir verknüpfen dieses Paket mit npm link und binden es dann wie npm link @bla/bla in das Projekt ein.
Sowohl das Paket als auch das Projekt verwenden dieselbe Version von React und React-Dom.

In das Projekt fügen wir das Paket wie folgt ein:

import Bla from `@bla/bla`

const RenderBla = ({...props}) => <Bla {...props} />

export default RenderBla

Leider besteht der Fehler weiterhin.
Invalid hook call. Hooks can only be called inside of the body of a function component.

Was kann uns fehlen?

"externals": {
  "react": "react",
  "react-dom": "react-dom"
}

Dieser hat das Problem für mich behoben, vielen Dank, Mann ❤️

Field Customizer-Fehler bei Zugriff über externen Link (Sharepoint Online)

Eine spfx-Feldanpassungserweiterung mit einigen Fabric-UI-Komponenten, die beim Zugriff über einen Link je nach FabricUI-Version einen dieser Fehler erhalten:
https://reactjs.org/docs/error-decoder.html/?invariant=321 ,
https://reactjs.org/docs/error-decoder.html/?invariant=290&args []=A.%20Allgemein

Wenn die Seite aktualisiert wird, funktioniert alles ordnungsgemäß.
Ich habe keine React-Hooks im Code verwendet, nur React-Komponenten.
Habe auch keine Refs verwendet.

Ich denke, es könnte an der Fabric-UI liegen, weil beim Entfernen aller Fabric-UI-Komponenten kein Fehler auftritt.

Habe verschiedene Versionen von Fabic UI, 6.189.2, 6.214.0 und 7.114.1 ausprobiert und auch versucht, alle Fabric-UI-Referenzen durch Fluent UI zu ersetzen, das Problem besteht weiterhin

habe die React-Versionen überprüft, hier ist die Ausgabe
npm ls reagieren
+-- @microsoft/sp-webpart-workbench@ 1.9.1
| +-- @microsoft/office-ui-fabric-react-bundle@ 1.9.1
| | -- [email protected] deduped | +-- @microsoft/[email protected] | | -- [email protected] dedupliziert
| +-- @microsoft/sp-property-pane@ 1.9.1
| | -- [email protected] deduped | -- [email protected] dedupliziert
`[email protected]

Hallo alle,
Ich bin auch über diesen ärgerlichen Fehler gestolpert. In meinem Fall war dies letztendlich auch eine Fehlkonfiguration meines Webpack-Builds. Aber keines der vorgeschlagenen Dinge in dieser Ausgabe hat bei mir funktioniert. Daher möchte ich auch meine Erfahrungen teilen.

Meine Seite enthält mehrere Einstiegspunkte, und das SplitChunkPlugin kann Laufzeitblöcke erstellen. Da wir das Rails-Webpacker-Gem verwenden, wurde es standardmäßig so konfiguriert, dass es eine Laufzeit für jeden Chunk erstellt. Aber Webpack macht standardmäßig etwas Ähnliches, es enthält die Laufzeit in den Chunks.

Natürlich warnt die Dokumentation vor diesem Fall, aber man muss ihn finden. Wenn Sie optimization.runtimeChunk auf single setzen, wird eine separate Laufzeit erstellt. Dadurch wird verhindert, dass Ihr Build mehrere Kopien von React instanziiert, wenn React von mehreren Einstiegspunkten aus verwendet wird.

Siehe https://webpack.js.org/configuration/optimization/#optimizationruntimechunk

Hallo alle miteinander,
Ich habe das Problem, dass ich eine externe Lib verwenden möchte, die von einem CDN stammt und in einem <script> -Tag enthalten ist, sodass ich mit dem Code selbst nicht viel anfangen kann. Die Bibliothek verwendet React und Hooks, also bekomme ich die
3. You might have more than one copy of React in the same app Fehler.
Leider gibt es kein NPM-Paket für die Bibliothek: https://github.com/Anyline/anyline-ocr-anylinejs-module
Ich verwende CRA und das Projekt wird nicht ausgeworfen.

Eine kleine Beispiel -Sandbox erstellt.

Es wirft den gleichen Fehler, da das andere Paket auch Hooks verwendet, aber mit seinem eigenen React. Ich musste mein Paket in NPM veröffentlichen und es dann direkt aus NPM importieren. Dass

Ich bin vor kurzem auf dieses Problem gestoßen und frage mich, warum.
Ich habe es gelöst, indem ich es auf GitLab hochgeladen und per Adresse installiert habe.
Was ist der Unterschied zwischen Paket und lokalem Paket?

Ich habe festgestellt, dass ich die Meldung „Invalid Hook Call“ erhalte. wenn ich die Komponente, die den Hook aufruft, dynamisch lade.

Code-Sandbox

Der Test, der "App" statisch lädt, wird bestanden. Die beiden Tests, die es dynamisch laden (einer mit require , einer mit import als Funktion), geben beide den Fehler.

Warum es mich überhaupt interessiert: Ich versuche, einige Tests zu schreiben, bei denen ich jest.doMock verwende, um einige Dinge zu verspotten und dann das Modul, das ich testen möchte, gemäß der Dokumentation dynamisch zu laden. Ich verwende doMock anstelle von Mock, weil ich Dinge in verschiedenen Funktionen unterschiedlich verspotten muss. Sie werden jedoch feststellen, dass der Fehler ohne Spott auftritt.

Es wirft den gleichen Fehler, da das andere Paket auch Hooks verwendet, aber mit seinem eigenen React. Ich musste mein Paket in NPM veröffentlichen und es dann direkt aus NPM importieren. Dass

Ich bin vor kurzem auf dieses Problem gestoßen und frage mich, warum.
Ich habe es gelöst, indem ich es auf GitLab hochgeladen und per Adresse installiert habe.
Was ist der Unterschied zwischen Paket und lokalem Paket?

@catsheue war React1 === React2 true für dich?
Ich habe meine noch nicht in npm veröffentlicht, wollte aber wissen, ob das die Ursache ist

meins scheint React1 === React2 = true zu sein und ich habe keine Lösung gefunden, warum dies passiert, wenn ich meine Reaktionsbibliothek in ein Projekt importiere

Hatte das gleiche Problem mit yarn link , um eine lokale Bibliothek zu testen. Mein Fehler war, react und react-dom als Dev-Abhängigkeiten aufzulisten, nicht als Peer.

Also hätte ich yarn add --peer react react-dom machen sollen. Da ich bereits den Fehler gemacht habe, React als Dev-Abhängigkeit zu übergeben, musste ich schließlich node_modules aus meiner Bibliothek löschen. rm -rf node_modules; yarn hat das Problem für mich behoben.

Auch ich stand vor diesem Problem. In meinem Fall wurde es durch einen doppelten React von Storybook (v6.0.28) verursacht. Ich glaube, Sie können hier weitere Informationen finden .

Ich habe Storybook-Abhängigkeiten deinstalliert, node_modules gelöscht und yarn install erneut ausgeführt. Das hat bei mir funktioniert. Ich hoffe, es hilft jemandem, die Tränen und verschwendeten Stunden damit zu vermeiden.

Dieser Workaround funktioniert bei mir auch. Ich verwende Firebase Functions und habe sowohl im Stammverzeichnis meines Projekts als auch im Verzeichnis /functions/ node_modules #$. Wenn ich /functions/node_modules lösche, läuft meine App einwandfrei. Dies ist eine Problemumgehung, aber es ist ziemlich nervig. Hat jemand eine Problemumgehung gefunden, die es ermöglicht, dass beide node_modules -Ordner gleichzeitig existieren?

Für die Nachwelt und alle, die möglicherweise mit diesem Problem konfrontiert sind, wenn sie mdbootstrap in einer App verwenden, die mit create-react-app erstellt wurde.

Ich habe diesen Fehler gesehen, als ich verschiedene mdbootstrap-Komponenten wie Schaltflächen und Kartenbilder hinzugefügt habe. Die Konsolenausgabe, die index.js zur Fehlerbehebung gemäß dem Support-Artikel von React hinzugefügt wurde, gab beim Vergleich von Versionen true zurück. Also musste ich etwas anderes ausprobieren.

Die Lösung bestand darin, ein npm dedupe auszuführen

npm ls react

+-- [email protected]
| `-- [email protected]
`-- [email protected]

npm dedupe

npm ls react

+-- [email protected]
| `-- [email protected]  deduped
`-- [email protected]

Danach funktionierten alle Komponenten einwandfrei. Glückliche Tage.

Ich habe festgestellt, dass ich die Meldung „Invalid Hook Call“ erhalte. wenn ich die Komponente, die den Hook aufruft, dynamisch lade.

Code-Sandbox

Der Test, der "App" statisch lädt, wird bestanden. Die beiden Tests, die es dynamisch laden (einer mit require , einer mit import als Funktion), geben beide den Fehler.

Warum es mich überhaupt interessiert: Ich versuche, einige Tests zu schreiben, bei denen ich jest.doMock verwende, um einige Dinge zu verspotten und dann das Modul, das ich testen möchte, gemäß der Dokumentation dynamisch zu laden. Ich verwende doMock anstelle von Mock, weil ich Dinge in verschiedenen Funktionen unterschiedlich verspotten muss. Sie werden jedoch feststellen, dass der Fehler ohne Spott auftritt.

@ miket01 Genau das, was ich versuche (aber ohne Spott). Hast du eine Lösung gefunden?

Dabei bin ich auf folgendes gestoßen:

function HeadedSection (props) {
   if (!ReactDOMServer.renderToStaticMarkup(props.children))
        return null;

    const [hidden, set_hidden] = useState(props.hidden);

Durch Aufrufen von zuerst useState behoben:

function HeadedSection (props) {
    const [hidden, set_hidden] = useState(props.hidden);

    if (!ReactDOMServer.renderToStaticMarkup(props.children))
        return null;

Ich erhalte diesen Fehler immer noch, nachdem ich ihn viele Monate lang beiseite gelegt habe.

Ich verwende Null-Hooks in meinem Programm. Es gibt genau eine Kopie von react und eine Kopie von react-dom und sie sind die gleiche Version. Es gibt keine Verknüpfungen.

Es hatte teilweise funktioniert, bevor ich kürzlich versucht habe, ein paar Pakete zu aktualisieren, um Sicherheitsprobleme zu beheben. Ich verwende next.js und die Lösung bestand darin, einige Unterkomponenten von der Komponente der obersten Ebene auszuschließen, indem sie in {typeof window !== 'undefined' eingeschlossen wurden, aber jetzt funktioniert das auch nicht.

[18:50:42] (master) questions
// ♥ npm ls react
[email protected] /Users/Dan/work/b/questions
└── [email protected]

[22:46:34] (master) questions
// ♥ npm ls react-dom
[email protected] /Users/Dan/work/b/questions
└── [email protected]

[22:46:55] (master) questions
// ♥ npm dedupe
removed 55 packages, moved 46 packages and audited 1712 packages in 65.449s

33 packages are looking for funding
  run `npm fund` for details

found 26 vulnerabilities (15 low, 3 moderate, 8 high)
  run `npm audit fix` to fix them, or `npm audit` for details

Der Fehler wird ausgelöst, weil ReactCurrentDispatcher.current === null , aber ich kann nirgendwo in /node_modules/react/cjs/react.development.js finden, wo dies auf etwas eingestellt ist.

Kann mir jemand sagen, wo ReactCurrentDispatcher.current einen Wert bekommen sollte?
https://github.com/facebook/react/search?p=2&q=%22ReactCurrentDispatcher.current+%3D%22&type=code

Das sieht nach einem Kandidaten aus, aber dieser Code ist nicht in meinem react-development.js enthalten. Sollte es sein?

    const prevPartialRenderer = currentPartialRenderer;
    setCurrentPartialRenderer(this);
    const prevDispatcher = ReactCurrentDispatcher.current;
    ReactCurrentDispatcher.current = Dispatcher;

https://github.com/facebook/react/blob/702fad4b1b48ac8f626ed3f35e8f86f5ea728084/packages/react-dom/src/server/ReactPartialRenderer.js#L859

Ich erhalte diesen Fehler beim serverseitigen Rendern von next.js und dieser Code befindet sich in der Reaktionsquelle unter react-dom/server . Wie kann ich feststellen, ob /node_modules/react/cjs/react-development.js richtig ist?

UPDATE: Das war das Problem. Ich hatte webpack.config.externals in meiner next.config.js -Datei bearbeitet
https://github.com/vercel/next.js/issues/17592#issuecomment -712443172

Meine App gibt jedes Mal einen massiven Fehler (ungültiger Hook-Aufruf) aus, wenn ich versuche, eine materielle Benutzeroberfläche darin zu integrieren. Ich bin völlig neu bei React, also brauche ich Hilfe.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen