Next.js: Ungültiger Hook-Aufruf in 9.0.6

Erstellt am 10. Okt. 2019  ·  74Kommentare  ·  Quelle: vercel/next.js

Fehlerbericht

Beschreibe den Fehler

Wenn Sie verwenden, reagieren Sie auf eine Komponente, die sich außerhalb des Hauptprojektordners von Next.js befindet und Hooks verwendet. Am Ende wird der Fehler Invalid hook call angezeigt und die Anwendung wird unterbrochen. Komponenten ohne Haken funktionieren wie erwartet.

Der Fehler tritt in allen Versionen >9.0.5 wenn Sie die Webpack-Konfiguration so ändern, dass Dateien außerhalb des Hauptordners transpiliert werden. Es funktioniert gut in <=9.0.5

Reproduzieren

Überprüfen Sie die Repro unter https://github.com/baldurh/next-9.0.6-bug-repro

Erwartetes Verhalten

Der Code sollte nicht beschädigt werden, wenn Dateien außerhalb des Projektordners verwendet werden.

System Information

  • Betriebssystem: N / A.
  • Browser: N / A.
  • Version von Next.js: >=9.0.6

Zusätzlicher Kontext

Ich weiß, dass dies wahrscheinlich keine übliche Verwendung von Next.js ist, aber in unserem Projekt verwenden wir einen Monorepo und haben einen freigegebenen Ordner mit Komponenten, die von mehreren Anwendungen verwendet werden. Es wäre schön, wenn das wieder funktioniert. Wenn jemand eine alternative Konfiguration findet, die wir verwenden könnten, würde ich das auch gerne tun 🙂

story 3 needs investigation

Hilfreichster Kommentar

Hallo, ein Update zu diesem Thema? Wir haben einen Monorepo und stoßen genau auf dieses Problem.

Alle 74 Kommentare

@baldurh Dies ist in der Tat sehr ungewöhnlich, wenn Plattformen wie Jetzt nur der Ordner bereitgestellt werden, in dem sich die Next.js-App befindet. Dies ist besser, da Sie sonst zuerst alle externen Module kennen müssten. 2 bessere Alternativen sind:

  • Verschieben Sie alles in eine einzelne Next.js-App
  • Verwenden Sie lerna oder private npm-Pakete oder ähnliches

@lfades danke für die Antwort. Keine dieser Optionen steht uns zur Verfügung und wir stellen sie nicht für Now oder ähnliches bereit. Wir haben anfangs Garnarbeitsbereiche verwendet, dann aber Bazel integriert und es spielt nicht gut mit der Verknüpfung von Garnarbeitsbereichen. Npm-Pakete bedeuten, dass wir die gemeinsam genutzten Module nicht so schnell entwickeln können, wie wir möchten. Es ist einfach zu viel Aufwand.

@baldurh Ich bin gerade mit next-i18next darauf gestoßen, da wir verschachtelte NextJs-Apps als Beispiele haben. Haben Sie eine Problemumgehung gefunden?

@isaachinman Wir haben nicht. Wir haben es aus anderen Gründen noch nicht geschafft, ein Upgrade auf 9.x durchzuführen, daher habe ich mich nicht damit befasst. Hat jemand eine Vorstellung davon, wo sich der Code, der dies beeinflusst, befinden könnte? Ich würde das Problem gerne besser verstehen.

Ich hatte noch keine Zeit, mich damit zu beschäftigen, aber wenn jemand einen Repro benötigt: Klone next-i18next , cd in examples/simple und aktualisiere die NextJs-Version auf> = 9.0.6.

Es ist derzeit auf 9.0.3, also ist dies technisch eine bahnbrechende Änderung an einem Patch.

Ich hatte kürzlich einen ähnlichen Fehler und musste auf 9.0.5 (und React 16.8.x) downgraden. Ich habe das Problem, das ich bei der Verwendung von MDX durch Next gesehen habe, eingegrenzt, aber darüber hinaus habe ich keine konkreten Details.

Ich habe mich mit einem ziemlich großen Projekt beschäftigt, das auf Next & next-i18next basiert.

Ich habe gesehen, dass dieser Fehler aus drei Gründen ausgelöst werden kann:

  1. Falsch ausgerichtete React & React-Dom-Versionen - gelten nicht für meine App
  2. 2 Versionen von React-Dom importiert - nicht auf meine App angewendet
  3. Unsachgemäße Verwendung von React-Hooks - Ich verwende keine Hooks, aber einige Bibliotheken sind es, und es sieht so aus, als ob es für alle anderen funktioniert.

Das Seltsame ist, dass es nur beim Produktionsaufbau passiert.

@timneutkens @Timer Entschuldigung, dass Sie dies markiert haben, aber ich würde mich über einige Beiträge von Ihnen

Anscheinend haben Sie react als Alias ​​verwendet, aber nicht react-dom . Kannst du das versuchen?

@ Timer Danke. Ich habe es versucht, aber es hatte keine Wirkung

Ich konnte dies gerade im Repro beheben, indem ich die Abhängigkeiten react und react-dom eine Ebene nach oben verschob. Ich habe die Änderungen nur vorangetrieben, wenn jemand sie ausprobieren möchte. Ich habe es bei unserem eigentlichen Projekt nicht ausprobiert, aber ich hoffe, dass es für uns funktioniert. Vielleicht könnte dies das Problem auch für @isaachinman , @jaredcwhite und @felixmosh lösen?

@Timer Ich habe dies in unserem Projekt zum react node_modules Ordner yarn why react geholfen 😄). Wir hatten sowieso vor, das Storybook in ein separates Projekt zu verschieben, daher denke ich, dass diese Lösung in unserem Fall funktionieren wird.

Ah ja. Falsch veröffentlichte node_module -Pakete verursachen dies (mit Abhängigkeiten von react(-dom|) anstelle von Peer-Abhängigkeit).

Ich konnte dies gerade im Repro beheben, indem ich die Abhängigkeiten react und react-dom eine Ebene nach oben verschob. Ich habe die Änderungen nur vorangetrieben, wenn jemand sie ausprobieren möchte. Ich habe es bei unserem eigentlichen Projekt nicht ausprobiert, aber ich hoffe, dass es für uns funktioniert. Vielleicht könnte dies das Problem auch für @isaachinman , @jaredcwhite und @felixmosh lösen?

Können Sie die Änderungen, die Sie in diesem Repo vorgenommen haben, näher erläutern?

Ich führe npm ls react oder npm ls react-dom Ich habe nur meine nächste App in der Liste.

@felixmosh Sorry, anscheinend ist der Push gestern für mich fehlgeschlagen. Jetzt sind die Änderungen auf jeden Fall dort 😅 zog ich react und react-dom von der app Ordner in den Stammordner so jetzt Sie tun müssen , yarn/npm install sowohl in der app Ordner und der Stammordner, bevor Sie den app ausführen. Hoffe das ist klar genug.

Wir müssen einige Änderungen an unserem Build-System vornehmen, damit dies in der Produktion funktioniert, sodass diese Lösung für uns immer noch ein bisschen problematisch ist 😝

Vielen Dank für die Erklärung, ich werde warten, bis das nächste Team es gelöst hat. Klingt ein bisschen komisch, um Reaktionsabhängigkeiten auf die Wurzel meines Mono-Repos zu setzen ...

@felixmosh Ja, ich stimme dir irgendwie zu. Wenn Sie jedoch so etwas wie Garnarbeitsbereiche verwenden, ist dies genau das, was dieses Werkzeug tut. Wenn Sie in zwei oder mehr Projekten dieselbe Abhängigkeit haben, werden die Abhängigkeiten in das Stammverzeichnis verschoben. Es ist schön, weil es sicherstellt, dass Sie in allen Ihren Projekten dieselbe Version der Abhängigkeiten haben. Aber wenn Sie kein solches Tool haben, müssen Sie es selbst verwalten, was in der Tat etwas umständlich ist. Ich bin damit einverstanden, dass die beste Lösung darin besteht, dass das Next.js-Team einen Blick darauf wirft und dies für uns alle löst

Das einzige Problem zu lösen und react und react-dom eine Ebene höher zu bringen und den Server vom Stamm aus auszuführen, ist die einzige Problemumgehung, die derzeit unter 9.1.5 funktioniert. Verknüpfen von https://github.com/facebook/react/issues/13991 und https://github.com/facebook/react/issues/15315#issuecomment -479802153 als Referenz, da ich diese Links vor diesem Problem gefunden habe.

Hallo, ein Update zu diesem Thema? Wir haben einen Monorepo und stoßen genau auf dieses Problem.

Treffen Sie mit dem gleichen Problem.
v9.0.5 funktioniert hervorragend mit Hooks für Komponenten, die außerhalb des rootFolder importiert wurden.

Ab 9.0.6 bis 9.1.6-canary.5 haben die gleichen Probleme.

Das Problem tritt nur auf der Serverseite auf. Wenn SSR deaktiviert ist (z. B. externe Komponente über Dynamic laden), funktioniert alles wie erwartet für Versionen> = 9.0.6.

@nodkz Es ist ein Problem bei der Lösung von Reaktionspaketen, daher tritt es nur im Knoten auf.

@Timer Dieses Problem wurde für "6 Versionen" zum "nächsten" Meilenstein verschoben. Es verhindert, dass ich auf die neueste Version aktualisiere.

Ich habe den ganzen Tag Zeit in der Unterkunft damit verschwendet, weiß nicht, woran es liegt, habe sogar versucht, das Problem zu umgehen (was nicht funktioniert hat).

Benötigen Sie Hilfe bei der Untersuchung einer Richtung?
Hast du ein Bauchgefühl?
Warum passiert das nur beim Produktionsaufbau?
Was wurde von 9.0.5 in 9.0.6 geändert, was damit zusammenhängen könnte?

Danke 🙏🏼

Ich denke, dass ich das Problem gefunden habe !!!
Ich denke, dass es eine Kombination von 2 Dingen ist:

  1. Verwendung von sym-link für node_modules
  2. i18next / react-i18next waren in Server-Bundles nicht extern !!
    image
    In meinem Fall beschwert es sich beim i18next useTranslation hook, wenn es beim Produktionsaufbau explodiert ...

Daher habe ich den Grund untersucht, warum es überhaupt Knotenmodule in Server-Bundles gibt (Best Practice für Server-Bundles besteht darin, sie extern zu machen).

Ich habe gesehen, dass next einige Ausnahmen für next lib hat (warum?). Der lustige Teil ist, dass dieser reguläre Ausdruck alle Libs abfängt, die mit next/dist/ enden, so wie i18next & react-i18next !!

Wenn Sie dies ändern:

res.match(/next[/\\]dist[/\\]/) 

in

res.match(/[/\\]next[/\\]dist[/\\]/) 

Das Server-Bundle schließt alle Bibliotheken aus, die nicht next und endet mit next/dist , und das Problem wurde behoben!

Für mich ist das Hauptproblem die neue Art und Weise, wie Anfragen gelöst werden: https://github.com/zeit/next.js/blob/canary/packages/next/build/webpack-config.ts#L446

Da wir Komponenten außerhalb des Projektstamms haben, löst die Anforderungsauflösung einen Fehler aus, der dazu führt, dass react in den Server-Chunks gebündelt wird. Und deshalb bekommen wir den Fehler Invalid hook call auf dem Server.

@baldurh context in dem von Ihnen verknüpften Ausdruck wird vom Webpack bereitgestellt und unterscheidet sich vom Kompilierungsstamm (Ihrem Projektverzeichnis).
Es ist immer das Verzeichnis der Datei, die die Anforderung ausgibt.

Recht. Ich habe dies gepatcht, damit es für uns jetzt funktioniert. Ich denke, wir werden irgendwann die Struktur des Codes so ändern, dass die Abhängigkeiten auf einer oberen Verzeichnisebene geteilt werden. Selbst wenn react im externen Ordner (außerhalb des Stammverzeichnisses) verfügbar ist, wird der Fehler dennoch angezeigt.

Ich versuche, ein verknüpftes Paket zu verwenden, und es tritt das gleiche Problem auf. Leider funktioniert keine der Korrekturen von https://github.com/facebook/react/issues/13991 🙁

Ich habe auch das gleiche Problem mit einer Komponentenbibliothek, die mit yarn link verknüpft ist. Dies hat bis v9.0.6-canary.4 funktioniert und jetzt bin ich in der gleichen Position wie einige andere Kommentatoren und kann darüber hinaus kein Upgrade durchführen. Ich habe die Änderung an dieser PR https://github.com/zeit genau festgelegt /next.js/pull/8739

Meine Komponentenbibliothek verwendet react , react-dom und styled-components . Die Konfiguration hierfür ist wie folgt

  • Die Pakete wurden als devDependencies hinzugefügt und in peerDependencies aufgenommen
  • Die Pakete wurden als extern in meine Webpack-Konfiguration aufgenommen
  • In meiner nächsten Konfiguration wurden diesen Paketen Auflösungs-Aliase hinzugefügt
  • Transpilierte das Komponentenbibliotheksmodul mit Next-Transpile-Modulen

Aktualisieren

Ich konnte dies beheben, indem ich diese Module in die externen Server einbaute. Vielen Dank an @HosseinAgha in diesem Kommentar https://github.com/martpie/next-transpile-modules/issues/50#issuecomment -558318688

if (isServer) {
  config.externals = [
    'react',
    'react-dom',
    'styled-components',
    ...config.externals
  ]
}

Ich sehe genau die gleichen Probleme, keine der Problemumgehungen hat bisher für mich funktioniert.

Mein Paket funktioniert, wenn ich es veröffentliche und installiere (und resolve.alias in meiner next.config.js verwende).

Das Ausführen eines Entwickler-Builds mit dem über yarn link @mypackage verknüpften Paket führt jedoch immer zu einem ungültigen Hook-Fehler.

Ich konnte es auch zum Laufen bringen, indem ich node_modules/dist/build/wepack-config.js änderte und die in https://github.com/zeit/next.js/pull/8739 hinzugefügten Zeilen auskommentierte

Was ich sehe, wenn ich baseRes und res protokolliere, ist, dass die if-Bedingung wie folgt ausgelöst wird:

  • /myApp/node_modules/react/index.js! == /myApp/node_modules/myPackage/node_modules/react/index.js
  • Nach meinem Verständnis wird dies ausgelöst, wenn der Pfad nicht identisch ist, auch wenn die Datei / Version zu 100% identisch ist

Aktualisieren:

Wir haben es geschafft, das Problem zu umgehen, indem wir unser Paket auf Garnarbeitsbereiche umgestellt haben (obwohl unser Repo nur ein einziges Paket enthält).
Wir haben unseren Code von ./src nach ./package/our-package-name/src verschoben und Garnarbeitsbereiche eingerichtet => https://classic.yarnpkg.com/de/docs/workspaces/

Dies umgeht das Problem, da dadurch allgemeine Abhängigkeiten in den Ordner ./node_modules der obersten Ebene verschoben werden und ./package/our-package-name/node_modules weitgehend leer bleibt.

Wenn wir also unser Paket als nächstes verknüpfen, wird keine zweite Version von react mehr abgerufen (da es nicht in unserem Ordner "node_modules" für Pakete enthalten ist) und alles funktioniert wie es sollte.

Ich habe das gleiche verdammte Problem. ¬¬ '

Wir brechen im Allgemeinen das Fluchen zusammen, da es gegen den Verhaltenskodex verstößt.

Entschuldigung, ich war wütend auf diesen Fehler. Eigentlich mag ich zu viel von Next.JS. Aber niemand kann es verwenden, weil dieses Problem langweilig ist.

Dieses Problem tritt auf, wenn wir mit externen lokalen Paketen und next-transpile-modules .

Da wir bei der neuesten Version von Next.js bleiben möchten, werde ich versuchen, einen Patch an Next.js zu senden, wenn ich die Hauptursache finde.

Nach der Installation von [email protected] habe ich das gleiche Problem
Meine Abhängigkeiten sind [email protected] , [email protected] , [email protected] und natürlich viele andere Bibliotheken (aber vor der Installation von next-i18next funktionierte alles). Wenn jemand eine Problemumgehung hat, könnte dies großartig sein: +1:

Vielen Dank, dass Sie dieses Problem veröffentlicht haben. Ich hatte auch Probleme mit der Verknüpfung unseres Design-System-Pakets (React Component Library). Wir transpilieren es auch mit https://github.com/martpie/next-transpile-modules.

Das hier vorgeschlagene Update hat bei uns funktioniert:

  • Verknüpfen Sie Ihre Bibliothek mit Ihrem Ordner node_modules (wir haben dies mit unserem eigenen Dienstprogramm anstelle von npm link getan, sollten aber grundsätzlich gleich sein).
  • Fügen Sie Ihrem next.config.js Folgendes hinzu:
// next.config.js
const nextConfig = {
    webpack: (config, options) => {
        // modify the `config` here

        if (options.isServer) {
            config.externals = ["react", ...config.externals];
        }
        config.resolve.alias["react"] = path.resolve(__dirname, ".\\node_modules\\react");

        return config;
    },
};
// more plugins etc...

Unsere alternative Problemumgehung, für die keine Konfiguration erforderlich ist

  • Symlink alles außer den node_modules aus Ihrem Paket. Ich habe mein eigenes Dienstprogramm dafür erstellt, kann es vielleicht auf Github posten.

Aber es wäre schön zu sehen, dass dies in NextJS behoben wurde. Ich habe so viel Zeit damit verbracht zu verstehen, warum der Webpack-Alias ​​für alle meine Nicht-NextJS-Projekte funktioniert hat :)

PS. Ich habe keine Ahnung, wie sich dies auf einen Produktionsaufbau auswirken würde, aber wir würden dies nur während der Entwicklung verwenden

if (options.isServer) {
            config.externals = ["react", ...config.externals];
        }

react ist bereits serverseitig extern.

config.resolve.alias["react"] = path.resolve(__dirname, ".\\node_modules\\react");

Dies wird das Problem nicht lösen.

Wie bereits erwähnt, hängt dieses Problem mit Ihren Abhängigkeiten in Abhängigkeit von react wohingegen sie ein peerDependency auf react (und bei Bedarf reagieren sollten).

@ Timneutkens

Nein, das ist nicht immer der Fall. Ich habe sicher als Peer-Abhängigkeiten reagiert und reagiert. Das Problem tritt jedoch weiterhin auf, wenn Sie beispielsweise Ihre Bibliothek mit einem nextjs-Projekt verknüpfen. Was dann passiert, ist, dass Sie einen node_modules Ordner in Ihrer Bibliothek haben (zumindest wenn Sie jemals npm i oder npm link in diesem Bibliotheksordner ausgeführt haben).

Wenn React aus diesem Bibliotheksordner aufgelöst wird, wird es in den Ordner in diesem node_modules -Ordner aufgelöst, und Sie erhalten zwei Kopien von React, die das Problem verursachen. Wenn ich den Ordner node_modules in meiner Bibliothek lösche oder ihn mit etwas anderem als npm link installiere, funktioniert dies natürlich (wenn Sie Peer-Abhängigkeiten oder genau dieselbe Reaktionsversion verwenden).

Um dies während der Entwicklung zu lösen, möchten Sie in der Lage sein, als Alias ​​zu reagieren, um alle zu zwingen, dieselbe Version zu verwenden. Aufgrund der hier erwähnten Probleme hat dies in der aktuellen NextJS-Version keine Auswirkung, ohne den Teil config.externals ... hinzuzufügen (zumindest für mich), wahrscheinlich wie die Leute hier aufgrund einiger Änderungen erwähnt haben, wie hier angegeben # 8739?

Ein ähnliches Problem tritt bei mir auf, aber (möglicherweise) aufgrund der Material-UI-Bibliothek (wie in # 10162 beschrieben) bestand meine vorübergehende Korrektur vorerst darin, npm run clean in meine preserve und hinzuzufügen dev Skripte wie hier beschrieben:
https://github.com/zeit/next.js/issues/10162#issuecomment -612501431

@timneutkens Ich verstehe, dass das eigentliche Problem darin besteht, wie diese Abhängigkeiten ihre eigenen Deps auflisten (deps vs peer-dep), aber eine Idee, was wir in unserer eigenen App tun können, um dies dauerhafter zu beheben?

@ Ryan-0 Hast du ein spezielles Setup? Wäre es überraschend, wenn Material, das Ui nicht auflistet, als Peer-Dep reagiert? Verwenden Sie eine sehr alte Reaktionsversion oder einen Symlink?

Kein spezielles Setup. Kein Symlinking und Reagieren. 16.13.1 -> Wir haben einige andere Deps, die das Problem möglicherweise fair machen, aber zumindest nach diesem Repro scheint es vielleicht mit Material-UI / Core zu tun zu haben (die wir auch verwenden):
https://github.com/zeit/next.js/issues/10162

@ Ryan-0 Gibt es einen Node_Modules-Ordner mit React in Ihrem Material-UI-Ordner?

Beginnt die Arbeit auch nach dem Ausführen von npm dedupe?

Nein, es sieht nicht so aus, als gäbe es einen verschachtelten Knotenordner. Deshalb bin ich verwirrt darüber, wie der Fehler auftritt. und nein npm dedupe hat nicht funktioniert :(

Seltsamerweise scheint die Verwendung von resolve.alias keine Auswirkungen auf Pakete außerhalb des Projektstamms zu haben.

Hier ist meine next.config.js Datei:

const path = require('path')

module.exports = {
  webpack: config => {
    const { alias } = config.resolve || {}
    alias.react$ = path.resolve('node_modules/react')
    alias['react-dom$'] = path.resolve('node_modules/react-dom')

    config.resolve = {
      ...config.resolve,
      alias,
    }

    return config
  }
}

Ich verwende yarn link mit einem lokalen Paket, das in einem Lerna-Monorepo vorhanden ist. Sein node_modules enthält keine Kopie von react , aber die monorepo Wurzel des Fall ist. Ich würde nicht erwarten, dass dies einen Unterschied macht, solange resolve.alias verwendet wird, aber das ist leider nicht der Fall. Nachdem ich die Kopie von react aus dem Monorepo-Stammverzeichnis entfernt habe, wird stattdessen ein Cannot find module 'react' -Fehler angezeigt.

Hat jemand eine gute Lösung dafür gefunden?

Ich habe eine verknüpfte nächste Bibliothek, die ich mit next-transpile-modules , um sie meinem 'Consumer'-Projekt hinzuzufügen. Ich habe den Alias react in meinen next.config.json hinzugefügt, wie in den Dokumenten erwähnt, aber es war nicht genug. Ich erhalte immer noch den Fehler doppelter Abhängigkeiten für React.

Sie können versuchen, relative-deps von @mweststrate zu verwenden

Hat jemand eine gute Lösung dafür gefunden?

Ich habe eine verknüpfte nächste Bibliothek, die ich mit next-transpile-modules , um sie meinem 'Consumer'-Projekt hinzuzufügen. Ich habe den Alias react in meinen next.config.json hinzugefügt, wie in den Dokumenten erwähnt, aber es war nicht genug. Ich erhalte immer noch den Fehler doppelter Abhängigkeiten für React.

Ja, siehe meinen Beitrag oben. Sie müssen den Teil config.externals in meinem Beispiel hinzufügen. Dann funktioniert der Alias ​​wieder

@johot Ich habe deine Lösung ausprobiert, aber es hat bei mir nicht ganz funktioniert. Ich bekam einige seltsame Fehler, aber hauptsächlich diesen: cannot destructure property 'query' of 'Object(...)(...)' as it is null nachdem ich Ihre Lösung ausprobiert hatte. Das in diesem Fall als null angesehene Objekt ist useRouter von next/router .

@aleclarson Danke für den Tipp. Ich werde es versuchen, wenn ich es beim nächsten Setup nicht zum Laufen bringen kann. Verwenden Sie es derzeit?

Wenn Sie next-transpile-modules und Yarn verwenden, ist die Lösung ganz einfach: https://github.com/martpie/next-transpile-modules#i - haben Probleme mit duplizierten Abhängigkeiten -invalid-hook-call-error-in-react

Wenn Sie npm , suche ich immer noch selbst nach einer Lösung: c

Ok, meine endgültige Lösung bestand darin, von yarn link auf yalc zu migrieren. Ich habe eine Schluckaufgabe, die nach Dateiänderungen sucht und die Dateien in meinen Ordner dist kopiert und die Änderungen dann in den yalc-Speicher überträgt.

In meinem 'Consumer' habe ich tsconfig.json geändert, um die Pfade wie folgt aufzulösen:

 "paths": {
      "~/*": ["/src/*"],
      "my-library/*": ["./node_modules/my-library/dist/*"]
    },

und in den next.config.js ich folgendes hinzugefügt:

 experimental: {
      jsconfigPaths: true, // enables it for both jsconfig.json and tsconfig.json
    }

Als nächstes können Sie die Pfade basierend auf tsconfig.json paths auflösen. Mehr Infos hier .

Lange Rede, kurzer Sinn: Das Kombinieren von yalc + next-transpile-modules mein lokales Entwicklungs-Setup erheblich verbessert. Keine doppelten Abhängigkeiten und seltsamen Fehler. Das Verhalten beim direkten Hinzufügen des Moduls mit yarn add und beim Verknüpfen des Moduls mit yalc ist ziemlich gleich.

Wenn Sie eine lokal verknüpfte Bibliothek verwenden, die von styled-components abhängt, lesen Sie Folgendes: https://styled-components.com/docs/faqs#linking -in-an-ssr-Szenario

In server/index.js :

const moduleAlias = require('module-alias');
moduleAlias.addAlias('styled-components', path.join(__dirname, '../node_modules/styled-components'));

Aber wir mussten auch Folgendes in next.config.js hinzufügen:

config.resolve.alias['react'] = path.resolve(__dirname, './node_modules', 'react');
config.resolve.alias['react-dom'] = path.resolve(__dirname, './node_modules', 'react-dom');
config.resolve.alias['prop-types'] = path.resolve(__dirname, './node_modules', 'prop-types');
config.resolve.alias['styled-components'] = path.resolve(__dirname, './node_modules', 'styled-components');

Ich hoffe es hilft.


Getestet mit:

Weiter: 9.3.5
Reaktion: 16.13.1
gestylte Komponenten: 5.1.0

Leute, einfache Korrektur, entfernen Sie Ihre globale Version von react, next und react-dom, indem Sie Folgendes tun:
npm remove -g react next react-dom

Leute, einfache Korrektur, entfernen Sie Ihre globale Version von react, next und react-dom, indem Sie Folgendes tun:

npm remove -g react next react-dom

Ich bin froh, dass das für Sie funktioniert hat, aber ich bezweifle, dass viele Leute in diesem Thread diese Abhängigkeiten global installiert haben.

Nicht nur Web!
reagieren 16.9
reaktionsnativ 0,62
Läuft auf Android
Vielleicht der kleinste Reproduzent in der Geschichte?

import React, { Component, useState } from 'react';
import {
  AppRegistry,
} from 'react-native';

function hooker() {
  const [count, setCount] = useState(0)
}

class ClassA extends Component {
  constructor(props) {
    super(props)
    //hooker();  //Invalid hook call Error
  }
  componentDidMount(){
    //hooker();  //Invalid hook call Error
  }
  render() {
    hooker();  //Invalid hook call Error
    return (      
      null   
    );
  }
} 
export default function App(props) {
  //hooker();  //No problem
  return (
    <ClassA/>
  );
};

AppRegistry.registerComponent('default', () => App);

Ich habe mich auch diesem Problem gestellt und es bekämpft, um yarn anstelle von npm (mit npm hat es nicht funktioniert) und https://github.com/vercel/next.js/ zu verwenden. Issues / 9022 # issuecomment -616169466

Gibt es dafür überhaupt eine Lösung?

Nur komplett mit Version 9.4.4 stecken.

Problem auf HOC für private Routen unten. Ich habe auch versucht, withRouter aber dann wird der gleiche Fehler stattdessen auf die umschlossene Komponente geworfen.

import { useRouter } from 'next/router'

function withPrivateRoute(WrappedComponent) {
const router = useRouter();                    //**** ERROR IS THROWN HERE *******
class WPR extends React.Component {
    componentDidMount(){
        console.log('wrappeed', WrappedComponent);
        // const { router } = this.props;
        const intendedRoute = router.pathname;
        // const isAdmin = !!cookies.get('isAdmin');
        // const isAuthenticated = !!cookies.get('username');
        const isAuthenticated = false;
        const isAdmin = false;
        if (!isAuthenticated) {
            router.push({
                pathname: '/login',
                query: { from: intendedRoute },
            });
        }
        if (
            isAuthenticated &&
            router.pathname.includes('admin') &&
            !isAdmin
        ) {
            router.push('/');
        }
    }

    render() {
        return ({ ...props }) => <WrappedComponent {...props} />;
    }
}
return WPR;
 }

  export default withPrivateRoute;

Ich hatte das gleiche Problem, also musste ich zu meinem vorherigen Zweig zurückkehren (wo ich davon ausging, dass dieses Problem nicht vorhanden war) und den neuesten Code Datei für Datei hinzufügen und feststellen, dass das Problem vorliegt

import { useToasts, AppearanceTypes } from 'react-toast-notifications';

export const showToast = (message: string, appearance: AppearanceTypes) => {
    const { addToast } = useToasts();
    addToast(message, {
        appearance,
    });
};

Ich habe einen Toast-Service verwendet und bei jeder Anfrage, wenn ein Fehler auftritt, wird showToast angezeigt, aber jetzt mit diesem Fehler glaube ich nicht, dass ich diesen Service verwenden werde

Ich kann bestätigen, dass dies mit der PR https://github.com/vercel/next.js/pull/8739 von @arcanis zusammenhängt
Wir verwenden ein Monorepo-Setup mit Rush und pnpm , wodurch der Grund für die Zusammenführung der genannten PR beseitigt wird. Dies bedeutet auch, dass der Punkt, den https://github.com/vercel/next.js/issues/9022#issuecomment -610255555 gemacht hat, für uns nicht gilt. Wir haben die folgende Struktur:

website
  dependencies: next, react, react-dom, library
library
  devDependencies: react, react-dom (for tests)
  peerDependencies: react, react-dom

Die library.devDependencies.(react|react-dom) sind Symlinks, die auf genau dieselben Dateien verweisen wie die website.dependencies(react|react-dom) . Es sieht jedoch so aus, als ob [email protected] , das in https://github.com/vercel/next.js/blob/f98e38c9b634b85e6679e7b5f953a9d98074cfc3/packages/next/lib/resolve-request.ts#L16 verwendet wird, nicht dem aktuellen Wert folgt Standardverhalten von Node.js durch Beibehalten der Symlinks.

Am Ende hatten wir Folgendes:

  1. Einrichten der Next-Transpile-Module zum Transpilieren unseres Codes in library
  2. Festlegen von resolve.symlinks = true in der Webpack-Konfiguration innerhalb von next.config.js
  3. Bearbeiten von externen Daten, die von library angefordert wurden, um von library/node_modules angefordert zu werden (damit der serverseitige Build Module korrekt auflöst)
  4. Kommentieren Sie die Zeile https://github.com/vercel/next.js/blob/f98e38c9b634b85e6679e7b5f953a9d98074cfc3/packages/next/build/webpack-config.ts#L601 aus

Dies funktioniert wie beabsichtigt, fühlt sich jedoch hackig an, da Next.js einige der wichtigen Websites wie die von Apple mit Strom versorgt. Ist es möglich, eine bessere Unterstützung für die Monorepos zu erwarten, die häufig zur Verwaltung von gemeinsam genutztem Code in diesen großen Projekten verwendet werden?

Ich habe damit herumgespielt und festgestellt, dass bei Verwendung eines HOC ein Fehler ausgegeben wird. Wenn ich jedoch eine Komponente als Wrapper verwende, funktioniert dies einwandfrei.

Wenn jemand interessiert ist, habe ich ein Repo, in dem Sie dies reproduzieren können: next-components-hooks-error

HOC-Test - Wirft einen Fehler

components/withPrivateRoute.js -> Komponente höherer Ordnung

import React, { useEffect } from 'react';
import { useRouter } from 'next/router';
const withPrivateRoute = WrappedComponent => {

    const router = useRouter();
    const [loading, setLoading] = useState(true);

    useEffect(() => {
        const user = localStorage.getItem('user');
        console.log(user);

        if (!user) {
            router.push('/login');
        } else {
            setLoading(false);
        }

    }, []);

    return ({ ...props }) => !loading && <WrappedComponent test={test} {...props}/>;
};

export default withPrivateRoute;

pages/hoc.js -> Funktioniert nicht (Seite mit dem HOC)

import React from 'react';
import withPrivateRoute from '../components/withPrivateRoute';

const HocTest = () => <p>Authorization HOC Test!</p>;

export default withPrivateRoute(HocTest);

Wrapper-Komponententest

components/AuthLayout.js -> Komponente (Wrapper)

import React, { useState, useEffect } from 'react';
import { useRouter } from 'next/router';

const AuthLayout = ({ children }) => {

    const router = useRouter();
    const [loading, setLoading] = useState(true);

    useEffect(() => {
        const user = localStorage.getItem('user');
        console.log(user);

        if (!user) {
            router.push('/login');
        } else {
            setLoading(false);
        }

    }, []);

    return !loading && (
        <React.Fragment>
            {children}
        </React.Fragment>
    );
};

export default AuthLayout;

pages/wrapper.js -> Seite mit der Wrapper-Komponente funktioniert es

import React from 'react';
import AuthLayout from '../components/AuthLayout';

const WrapperTest = () => (
    <AuthLayout>
        <p>Authorization Wrapper Test!</p>
    </AuthLayout>
);

export default WrapperTest;

hey @Timer gibt es da einen Fortschritt?

Ich löse mein Problem mithilfe von https://github.com/vercel/next.js/issues/9022#issuecomment -609969178 als Lösung.
Meine Fragen waren mit meiner Bibliothek Repo mit und yarn link ing es mit meiner app Repo
Beispiel
package.json

{
  "dependencies": {
    "next": "9.5.1",
    "myUILibrary": "git+ssh://[email protected]/MyRepo/library-web-ui.git#master",
    "react": "16.13.1",
    "react-dom": "16.13.1"
  }
}

und ich yarn link myUILibrary zu meiner lokalen Kasse MyRepo/library-web-ui der auch react installiert ist.

Vielen Dank @johot für die Veröffentlichung Ihrer Lösung

5 🌟 von 3 (ja! Alle Sterne und mehr!)

Ich kann die gleiche Erfahrung wie @ wasd171 in einem Rush + PNPM-Monorepo bestätigen. Ich werde in der Zwischenzeit nur ~9.4.4 .

Ich habe genau das gleiche Problem mit Rush + PNPM 👍

ok, ich hatte einen sehr dummen Fehler, der dieses Problem verursachte:

import React, { useState } from 'React';

Es sollte r EACT statt R EACT sein:

import React, { useState } from 'react';

Jep. Ich sehe dies auch in 9.5.x - Downgrade auf 9.4.4 funktioniert - Sie können dies auch mit next-site reproduzieren

Capture

Ich konnte diesen Fehler in 9.5.2 nicht beheben. Aber in 9.5.3 funktioniert bei mir alles perfekt ohne Tricks.

Ich benutze kein pnpm.

Ich habe zu früh gesprochen. Ich glaube auch nicht, dass es mit 9.5.3 funktioniert.

In 9.5.3 funktioniert es jetzt zuverlässig für mich. 🤷 Ich weiß nicht mehr, was los ist.

9.5.3 funktioniert bei mir nicht - gleicher Fehler. Ich benutze Rush + NPM. Gibt es eine bekannte Problemumgehung? (Übrigens können wir den Titel aktualisieren, da es sich nicht mehr um 9.0.6 handelt.)

Zu Ihrer Information, es war einer der Gründe, warum meine Organisation beschlossen hat, von npm auf yarn zu wechseln. Es spielt sich einfach (leider) viel schöner. Der Umzug ist nervig, aber wir sind jetzt ziemlich glücklich.

Transpiled Module mit Hooks funktionieren auch bei mir nicht.

Übrigens habe ich jedem, der dieses Problem bei der Verwendung von next-transpile-modules und npm , einen FAQ-Abschnitt geschrieben, in dem das Problem und mögliche Lösungen erläutert werden: https://www.npmjs.com/package/ next-transpile-modules # Ich habe Probleme mit doppelten Abhängigkeiten oder dem ungültigen Hook-Call-Fehler in der Reaktion

Ich habe es geschafft, dies zu lösen, indem ich die Versionsauflösung für Garn manuell im Projektstamm hinzugefügt habe. Anstatt alle Reaktionsabhängigkeiten in die Wurzel package.json , habe ich die folgenden Zeilen hinzugefügt:

  "resolutions": {
    "react": "16.13.1",
    "react-dom": "16.13.1"
  }

Siehe: https://classic.yarnpkg.com/de/docs/selective-version-resolutions/

Es ist erwähnenswert, dass in meinem Fall lokale Builds funktionierten, während Builds auf Vercel den Fehler Invalid hook call meldeten.

Ich habe ein ähnliches Problem in _app.js mit einer Catchall-Seite in Next 10 experimentiert

image

Hallo,

In meinem Fall hatte ich transpilierte Module, die auch über npm link verknüpft waren.

Abhängigkeiten wie React müssen anstelle regulärer Abhängigkeiten als peerDependencies werden, da mehrere Instanzen davon heruntergeladen wurden. Wenn Sie also den Fehler "Ungültige Hooks" haben, führen Sie die folgenden Schritte aus:

  1. Fügen Sie Ihr Drittanbieter-Modul als Abhängigkeit in Ihr Hauptprojekt ein.
  2. Führen Sie ein npm install , um alle Ihre Module zu installieren.
  3. Öffnen Sie Ihr Terminal / Ihre Konsole, navigieren Sie zum Modul und führen Sie dann sudo npm link .
  4. Navigieren Sie zurück zu Ihrem Hauptprojekt und führen Sie ein npm link @example/project . Wenn Sie Visual Studio Code verwenden, sollte in node_modules ein kleines Pfeilsymbol neben Ihrem Modulnamen angezeigt werden.
  5. Führen Sie Ihre npm run dev .

Auch hier müssen Sie React als PeerDependency anstelle einer regulären Abhängigkeit in Ihr @ example / project aufnehmen.

Ich hoffe das hilft!

Ich habe eine Monorepo mit einem next.js-Projekt im Inneren. Das gleiche Problem trat bei einem ungültigen Hook-Aufruf nach der Installation von storybook . Das Problem wurde durch Befolgen des Vorschlags von resolutions zur Stammebene package.json hinzugefügt:

"resolutions": {
  "react": "^17.0.1",
  "react-dom": "^17.0.1"
}

Ich bin mir nicht sicher, ob dies eine gute Lösung sein wird, wenn wir weitere Clients und Pakete hinzufügen.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen