React: Hooks + múltiples instancias de React

Creado en 27 oct. 2018  ·  285Comentarios  ·  Fuente: facebook/react

Para las personas que vienen de la búsqueda: primero lea esta página . ¡Contiene las correcciones posibles más comunes!

¿Desea solicitar una característica o informar un error ?

Mejora

¿Cuál es el comportamiento actual?

Tuve múltiples instancias de React por error.

Al intentar usar ganchos, obtuve este error:
hooks can only be called inside the body of a function component

Lo cual no es correcto ya que estaba usando componentes de funciones. Me tomó un tiempo encontrar la verdadera causa del problema.

¿Cuál es el comportamiento esperado?

Mostrar el mensaje de error correcto. Tal vez detecte que la aplicación tiene múltiples instancias de React y diga que puede ser la razón de los errores.

Hooks Discussion

Comentario más útil

Tuve el mismo problema y lo resolví agregando:

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

a la propiedad resolve en la configuración del paquete web de mi aplicación principal.

Obviamente, fue mi error usar dos copias de React, pero estoy de acuerdo en que sería genial si el mensaje de error fuera mejor. Creo que esto es quizás similar a: https://github.com/facebook/react/issues/2402

Todos 285 comentarios

Entonces, solo como aclaración: ¿estaba importando un enlace (digamos useState ) de un módulo react diferente al que se usó para representar el componente?

Estoy de acuerdo en que esto es confuso. Sin embargo, no estoy seguro si tenemos una forma de saber si algún otro módulo React se está procesando. AFAIK, tratamos de ejecutar React de forma aislada tanto como sea posible para que varias instancias de React puedan funcionar en el mismo contexto global sin problemas.

De lo contrario, probablemente podríamos actualizar el mensaje de error y mencionar este caso también si no es demasiado confuso.

Sí, comparé React1 === React2 y era false (React1 de index.js y React2 del archivo que usa el gancho). Cuando esto sucede, los ganchos fallan con el mensaje de error genérico anterior.

Este problema es para crear conciencia sobre este caso y tal vez mejorar el mensaje de error de alguna manera para ayudar a las personas que enfrentan esto. Sin embargo, probablemente sea muy extremo.

Sí, traté de vincular npm a un paquete que estoy creando. Lanza el mismo error ya que el otro paquete también usa ganchos pero con su propio React. Tuve que publicar mi paquete en NPM y luego importarlo directamente desde NPM. De esa manera el error desapareció, pero espero que esto se solucione ya que publicar un paquete sin probarlo es malo, obviamente

Los monorepos de Lerna también sufren esto cuando se define un enlace personalizado en un paquete y lo usa otro, ya que las dependencias enlazadas usan su propia copia de reaccionar.

Tengo una solución (pirata) en este momento usando npm-link-shared y un script prestart npm para reemplazar esencialmente la dependencia react un paquete con un enlace simbólico al otro, por lo que usan la misma instancia.

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

Tuve el mismo problema y lo resolví agregando:

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

a la propiedad resolve en la configuración del paquete web de mi aplicación principal.

Obviamente, fue mi error usar dos copias de React, pero estoy de acuerdo en que sería genial si el mensaje de error fuera mejor. Creo que esto es quizás similar a: https://github.com/facebook/react/issues/2402

@mpeyper Funciona. Gracias

@apieceofbart Eso funcionó para mí. Gracias por la sugerencia. 👍

Según tengo entendido, este problema surge cuando hay varias copias de React en el mismo paquete.

¿Es esto también un problema si dos paquetes separados con sus propias copias de React están iniciando sus propias aplicaciones React en elementos dom separados, como se describe aquí: https://medium.jonasbandi.net/hosting-multiple-react-applications-on- el-mismo-documento-c887df1a1fcd

Creo que este último es un patrón común de "integración" que se usa, por ejemplo, en el meta-marco de spa único (https://github.com/CanopyTax/single-spa).

También tengo este problema, incluso con exactamente las mismas versiones de reacción, el desarrollo de ganchos para publicar solos se rompe cuando se usa npm-link . Recibiendo el mismo mensaje inútil hooks can only be called inside the body of a function component . La solución de alias de @apieceofbart resolvió esto para mí. ¡Muchas gracias!

El mismo problema aquí cuando npm link un paquete en mi aplicación principal. No pude hacer funcionar babel-plugin-module-resolver .
Dice:
Could not find module './node_module/react'
Esto es molesto porque me impide probar mi componente localmente antes de publicarlo.

Resolví mi problema quitando el símbolo de intercalación en "react": "^16.7.0-alpha.2"
Aquí está el comentario completo: https://github.com/facebook/react/issues/14454#issuecomment -449585005

Estoy usando Yarn y solucioné esto forzando la resolución en mi package.json :

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

¡¡Aquí igual!!

Solo quería dejar una nota aquí para cualquiera que haya tenido este problema de la misma manera que yo.

Estamos ejecutando React y Rails con la gema react-rails y renderizando los componentes directamente en las vistas de Rails. Recibía este error cada vez que se publicaba una nueva versión de la aplicación, porque Turbolinks tomaba el nuevo paquete JS del <head> que cargaba una instancia adicional de React. La solución fue hacer que Turbolinks recargue la página completa cuando detecte que el paquete ha cambiado: https://github.com/turbolinks/turbolinks#reloading -when-assets-change

Esto parece haberlo resuelto para nosotros.

Estoy muy emocionado de finalmente poner Hooks en producción, y todos debemos un gran agradecimiento a todos los que lo hicieron posible. Es muy divertido trabajar con ellos y han hecho que mi código sea más corto y más declarativo.

Solo como un aviso, este problema sigue siendo relevante en la versión lanzada con el mismo mensaje de error inútil de "Los ganchos solo se pueden llamar dentro del cuerpo de un componente de función".

¿Es esto algo que se puede arreglar? Me imagino que podría volverse cada vez más frecuente a medida que más desarrolladores comiencen a implementar las nuevas funciones, y un mensaje de error más claro sería de gran ayuda en lugar de una "solución" absoluta.

¡Gracias de nuevo por todo el trabajo duro y felicidades por el lanzamiento! Es realmente un increíble conjunto de características.

Editar : Debería haber mirado más de cerca las relaciones públicas abiertas, solo encontré # 14690 que aborda esto. ¡Gracias @trespuntos!

@taylorham El enlace en la confirmación aún no apunta a nada. Lo esperaré, pero este es un problema que he tenido desde que uso ganchos en un paquete vinculado _(a partir de npm link )_ y es imposible trabajar con él localmente sin publicar.
Después de buscar varios problemas, pensé que se trataba de un problema con react-hot-loader que estaba compilando componentes en clases, pero incluso después de que lanzaron una versión con soporte para Hook , sigue fallando de la misma manera.
He probado muchos trucos diferentes pero no he tenido suerte. No sé por qué a todos aún no les ha llamado la atención este problema 🧐

@dotlouis Sí, es solo un mensaje de error actualizado hasta ahora y el problema en sí sigue siendo un dolor.

Lo único que me ha funcionado es hacer que cualquier aplicación que esté desarrollando dependa de la instancia de React de la biblioteca usando "react": "link:../my-library/node_modules/react" .

  • ninguna de las resoluciones propuestas funcionó para mí, y he estado intentando todo
  • tratando de instalar en un contexto de implementación de proyecto y muchos HOC
  • partir de un proyecto en blanco funcionó
  • sigo buscando la causa

[ok] para mí, la corrección no se trataba de package.json u otras causas de reacción doble: tenía un proveedor de temas global en la parte superior de mi aplicación, proveniente del contexto. Reemplazarlo con un "gancho useContext" (mientras lo reescribía como una composición funcional) parecía ser la única solución
Tal vez hay un problema cuando

<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)

Estoy desarrollando un componente donde hay una carpeta example que usa create-react-app .

Hacer esto en package.json resolvió este problema para mí:

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

@taylorham @DylanVann Gracias por sus aportes, muchachos. Desafortunadamente, todavía no funciona para mí.
Y no pude encontrar ninguna documentación sobre este protocolo link: que usó.
Básicamente, dice que "react-spring" (otra dependencia que también usa react como dependencia) no puede encontrar react-dom . ¿Puede señalarme alguna documentación sobre "react": "link:../some/path" , por favor?

También estoy usando el paquete de interfaz de usuario vinculado y pude solucionar este problema.
Debe exportar reaccionar renderToString desde la interfaz de usuario (paquete vinculado).
Creé la función de renderizado en el paquete vinculado.

Solo para un mejor contexto: https://github.com/facebook/react/issues/14257

Gracias @theKashey. @gaearon parece pensar que es el comportamiento normal. Entiendo que React no debe cargarse dos veces, pero ¿cuál es entonces la forma recomendada de trabajar con un paquete local vinculado?

También tuve problemas con los espacios de trabajo de Lerna al vincularlos correctamente. Este fue el truco que usé para que esto funcionara. Asegúrese de ejecutar npm install después.

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

Hay muchas formas de resolverlo, y las resoluciones de hilo generalmente no ayudarían; está más relacionado con la "herramienta de construcción"

  • para el uso del paquete web aliases - solo alias "duro" todo se agacha como react a un solo archivo
  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'))
});
  • para broma usa moduleNameMapper
"jest": {
    "moduleNameMapper": {
      "^react$": "<rootDir>/node_modules/$1",
    },

@theKashey gracias por sus ideas, esto tiene sentido cuando consideramos cómo se realiza la resolución del módulo (abajo, luego arriba en el árbol), pero desde el punto de vista del usuario, no lo encuentro muy práctico. Cuando npm link un paquete, espero que funcione sin tener que volver a cablear las dependencias explícitamente. Esto hace que desarrollar un paquete localmente sea bastante doloroso.

Esta es una piedra angular, así es como node_modules se diseñó para funcionar, es por eso que puede tener dos versiones de Button en dos versiones principales diferentes, y los módulos dependientes encontrarán fácilmente el "correcto" versión de un paquete.
Así es como debería funcionar todo el tiempo.

Las funciones internas Node.js son bastante sencillas: intente abrir un archivo agregando todos los prefijos conocidos (como node_modules ) o extensiones (como js , ts , json ); si no encuentra ninguno, vaya un directorio hacia arriba. La única forma de "arreglarlo": reemplace el sistema de resolución del módulo nodejs.

yarn pnp hará eso y podría resolver el problema. yarn workspaces , que podría _elevar_ paquetes compartidos a la parte superior, también resolverá el problema sin ninguna "magia" involucrada.

npm workspaces ? No existe ahora mismo.

De hecho, terminé cambiando mi proyecto para usar espacios de trabajo. Resuelve esto sin tener que usar resoluciones, y la estructura/elevación es beneficiosa de todos modos.

Este fue un rascador de cabeza. Probé la configuración resolve.alias del paquete web pero no funcionaba, también probé muchas configuraciones pero nunca logré que funcionara, lamentablemente, pero así es como finalmente logré que funcionara:

Aquí está mi estructura de carpetas:

Proyecto
|
+-- node_modules
|
+-- construir
| |
| +-- índice.js
|
+-- ejemplo (crear-reaccionar-aplicación)
| |
| +-- paquete.json

Tuve que modificar mi paquete.json dentro de la carpeta de ejemplo, esencialmente sacando la reacción de los nodos_módulos 'principales' del proyecto según la sugerencia de @jmlivingston, así es como terminó:

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

Ahora, después de eso, ejecuté npm install y luego ejecuté npm link , eso funcionó.

Esperemos que esto pueda ayudar a alguien más y ahorrar algo de tiempo.

Entonces, ¿alguna solución a este problema? He intentado tantas recomendaciones aquí como puedo y sin suerte. Estoy usando create-react-app y mecanografiado. Uso de React/React-dom 16.8.3. Este es un nuevo proyecto que creé hace 2 días, así que es bastante sencillo. Estoy usando useSpring() y animation.div. Gracias

@ guru-florida, ¿estás usando react-router por casualidad?

Estoy usando la misma pila que usted (mecanografiado y crear-reaccionar-aplicación) y mi problema con el atributo render . Cambiarlo a component funcionó.

Antes:

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

Después:

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

Espero eso ayude..!

@mikeyyyyyy No, no estoy usando React Router en este. Gracias por el consejo porque estaba en el último proyecto que probé usando Spring y tuve el mismo problema.

Tuve este problema con el enlace npm (en una aplicación de paquetes), el npm link .../whatever/node_modules/react no parece resolverlo, aunque funciona bien con componentes que no son ganchos

@tj Supongo que tienes un problema con ssr. La solución rápida es exportar las funciones de reacción o la reacción completa del paquete vinculado e importarlo en el paquete de su servidor

@seeden ahh no estoy usando SSR, solo un SPA con Parcel. Tengo un paquete de ui internamente para mis propias cosas y una aplicación en la que estoy trabajando, ambos tienen la misma versión react , parece extraño que haya un duplicado, pero tal vez sea un problema de Parcel

@tj oh, ya veo. Entonces buena suerte con este tema tan extraño. Pasé una semana con esto.

Entonces, ¿alguna solución a este problema?

No hay ningún problema aquí per se. Como se explica en esta página , React necesita que las llamadas useState() estén en el mismo objeto react que el objeto react "visto" desde dentro de react-dom . Si eso no es lo que le sucede, significa que está agrupando dos copias de React en la página, lo cual es malo en sí mismo y también rompe algunas otras funciones antes de Hooks. Así que querrás arreglarlo de todos modos. Esta página contiene formas comunes de diagnosticar para solucionarlo.

Dejamos esta discusión abierta para compartir soluciones particulares cuando las personas se encuentran con este problema. Pero no es un problema per se que pueda ser "arreglado" por nadie más que por ti.

Tuve este problema con el enlace npm (en una aplicación de paquetes), el enlace npm .../lo que sea/node_modules/react no parece resolverlo, aunque funciona bien con componentes que no son gancho

¿Te importaría crear un pequeño estuche de reproducción?

@gaearon lo hará, debería tener tiempo para profundizar un poco más la próxima semana

Afortunadamente, require-control solucionó nuestro problema con el contexto estático de yarn link + SSR + styled-components 4. Gracias @theKashey 👍

Intenté todo aquí y fallé. En realidad, era algo diferente que no está documentado aquí. Tenía que ver con la distinción entre mayúsculas y minúsculas de las importaciones de reacción . En algunos casos tuvimos:

import React from 'react'

Y en otros:

import React from 'React'

En algunos sistemas de archivos (unix, osx), esto hace que Webpack cree instancias de dos copias de React.

Esto causó una confusión extrema, ya que pude ver claramente que solo tenemos una copia de React; pero en cambio fue la forma en que lo estábamos importando.

La prueba en la documentación de reacción también sale bien, ya que obviamente solo usa minúsculas.

¿Esto parece que podría ser digno de una mención en los documentos?

Para mí, la razón de múltiples instancias de React fue Webpack DllPlugin. Para mi DLL de proveedor, no incluí react y react-dom en mi lista de entradas, sin embargo, tenía otras bibliotecas que requerían react o react-dom así que mi archivo DLL contenía react y react-dom (una revisión rápida del archivo JSON del manifiesto puede revelarlo). Entonces, cuando estaba ejecutando el código e importé React en la aplicación, lo estaba cargando desde node_modules , pero en el código de los proveedores se requería React desde su archivo DLL.

En general : tenga cuidado con los archivos DLL y asegúrese de que sus módulos incluidos no incluyan dependencias adicionales que no necesita, de lo contrario, los importará dos veces.

Pude arreglar esto actualizando react-hot-loader a 4.6.0

esto funcionó para las cosas de npm link en Parcel:

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

no estoy seguro de si eso es lo que intentará usar para una compilación de producción, parece un poco raro, pero funciona al menos para el desarrollo

@theKashey Dios mío , ¡funciona! Probé muchas soluciones diferentes que la gente sugiere relacionadas con estos problemas: manipular con package.json deps, rastrear "dos reacciones" en el proyecto, verificar si estoy rompiendo la *regla de los ganchos` (que estoy no), pero creo que su opción con:

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

nos permite mover nuestro proyecto al siguiente nivel, usando ganchos en nuestra app-as-a-lib .

Este es el resultado webpack.config.js

npm ls react

devoluciones

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

para mi

console.log(window.React1 === window.React2) devuelve verdadero
en este punto estoy pensando que es SSR el que causa el problema

Actualizar. De hecho, fue causado por el comportamiento SSR de React-apollo (https://github.com/apollographql/react-apollo/issues/2541)
Actualizar a 2.3.1 lo arregló

Hola chicos, nuestro equipo se enfrentó a este problema y tardó unos días en resolverlo.

las soluciones de trabajo para nosotros

Solución A: especifique la posición del paquete a buscar, como se mencionó anteriormente

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

Solución B: use webpack resolve.modules para priorizar la carpeta node_modules correcta para buscar módulos

antecedentes del caso y por qué sucede

Lo primero es lo primero, no es culpa de react, ni siquiera de lerna, pero es posible que react, webpack y npm-link deban asumir algunas responsabilidades.

Requisito de caso:

-No monorepo:

  • tener paquetes enlazados
  • el paquete con enlaces simbólicos ha exportado el componente usando ganchos
  • creando páginas del lado del cliente de reacción

    • Si trabaja en un monorepo

  • paquetes enlazados
  • los paquetes tienen diferentes versiones de dependencias (incluso la diferencia de versión del parche), por lo que incluso el espacio de trabajo se resolverá cuando 2 reaccionen instalados
  • el paquete de entrada importó un paquete con enlace simbólico que usa ganchos

Ejemplo

Estructura

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

Una vez que arranque con los espacios de trabajo, se resolverá para

- 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)

Y una vez que sirva ProductA con webpack o tal vez algo más, contendrá 2 instancias de reacción.

Código en ProductA, buscará ProductA/node_modules/react .

Pero el ComponentWithHooks importado buscará mono repo root/node_modules/react .

¿Por qué? ¿Recuerdas las reglas de búsqueda de npm? Si no puede encontrar el módulo en su propia carpeta node_modules, buscará los node_modules del padre...

Entonces, herramientas como webpack aplicaron esta regla de forma predeterminada a la perfección.
No tiene nada de malo que la solución de repositorio mono util se vuelva popular.
Y el paquete normal no notará esto, ya que la mayoría de ellos no requieren una sola instancia como reaccionar y redux.

Tengo este mismo problema usando una reproducción muy básica usando el ejemplo de espacios de trabajo de hilo: https://github.com/mwarger/yarn-workspace-hooks-repro

Tengo un component-library escrito a máquina y incluido en el paquete. El example-demo es lo que exhibirá este component-library y es una aplicación CRA recién creada. Todos los paquetes comunes se izan con hilo, por lo que, en teoría, solo debería haber una versión de reaccionar disponible. Sin embargo, la llamada React.useEffect que estoy haciendo en index.tsx provoca el error que me lleva a este problema de GitHub.

Todo funciona hasta que se agrega un gancho. Para reproducir el error, descomente las líneas 7-9 en component-library/src/index.tsx

Espero estar haciendo algo tonto que he pasado por alto. Indique cualquier paso que pueda seguir para tratar de remediar esto. ¡Gracias!

Edición de seguimiento: la salida del script de depuración sugerida a continuación imprime true para mí. Parece que no tengo dos React.

// 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);

Me tomó varias horas, así que podría valer la pena tomar una nota aquí.

En mi caso, puse una línea de <script defer src="./dist/bundle.js" /> en el encabezado de la plantilla HTML, que funciona normalmente cuando no se usan ganchos React. Todas las soluciones no funcionan y el cheque window.React1 == window.React2 devuelve true en este caso.

Dado que webpack inyectará la etiqueta de secuencia de comandos después, la plantilla no debería tener una etiqueta de secuencia de comandos propia. Elimine la etiqueta del script de la plantilla, haga que React sea funcional con ganchos (juego de palabras) nuevamente.

En mi caso, tengo una aplicación React que estaba vinculada a npm a una dependencia en la que estaba trabajando. Esto funcionará hasta que pueda arreglar un par de dependencias que necesitan mover react y react-dom a los departamentos de desarrollo y pares.

  1. Desde la aplicación: cd node_modules/react && npm link
  2. Desde la aplicación: cd node_modules/react-dom && npm link react
  3. Del paquete vinculado: npm link react

¿Por qué funciona? La página de advertencia de error menciona que "para que los Hooks funcionen, la importación de reacción desde el código de su aplicación debe resolverse en el mismo módulo que la importación de reacción desde el interior del paquete react-dom".

Todavía tengo este problema, a pesar de intentar todo lo anterior. Configuración estándar de webpack4/babel, con complementos preset-env y preset-react . Mis versiones react/react-dom están fijadas a 16.8.4 usando resoluciones de hilo (donde también el cheque window.React1 === window.React2 de arriba devuelve true ).

Esto es en el más básico de los usos:

import React, { useState } from "react";

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

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

¿Alguien tiene alguna otra idea?

EDITAR: para aclarar, el error se muestra como react.development.js:88 Uncaught Invariant Violation: Hooks can only be called inside the body of a function component. según el OP

En mi caso, tengo una aplicación React que estaba vinculada a npm a una dependencia en la que estaba trabajando. Esto funcionará hasta que pueda arreglar un par de dependencias que necesitan mover react y react-dom a los departamentos de desarrollo y pares.

  1. Desde la aplicación: cd node_modules/react && npm link
  2. Desde la aplicación: cd node_modules/react-dom && npm link react
  3. Del paquete vinculado: npm link react

¿Por qué funciona? La página de advertencia de error menciona que "para que los Hooks funcionen, la importación de reacción desde el código de su aplicación debe resolverse en el mismo módulo que la importación de reacción desde el interior del paquete react-dom".

¡Gracias! Esto funciona muy bien para mí. (incluso cuando uso el enlace npm y la situación mixta del enlace simbólico)

Intenté todo lo sugerido anteriormente y todavía tenía el error.

Con un poco de ayuda de @inverherive , descubrimos que enzyme-adapter-react-16 seguía causando problemas.

Si bien actualizamos react-test-renderer a la última versión (16.8.4) ya que solo recientemente agregó compatibilidad con ganchos, descubrimos a través npm ls react-test-renderer que la última versión de enzyme-adapter-react-16 (1.11.2 ) tenía una dependencia interna de [email protected] , que no admite ganchos.

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

Para solucionar este problema, además de seguir las correcciones de @chulanovskyi , como usamos yarn, agregamos resoluciones react-test-renderer a nuestro paquete.json. Esto obliga a todas las referencias de react-test-renderer a usar "16.8.4".

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

Esto fue mega frustrante, espero que esto pueda ayudar a alguien más. Gracias a @chulanovskyi y @theKashey por sus sugerencias también.

Esto funcionará hasta que pueda arreglar un par de dependencias que necesitan mover react y react-dom a los departamentos de desarrollo y pares.

@ajcrews (podría haberme perdido algo, pero) npm link en una biblioteca interna y esa biblioteca tiene react en peerDependencies y devDependencies y todavía necesitaba su corrija independientemente para resolver el error. ¡Buen hallazgo!

Estaba a punto de publicar pero encontré una solución.

Tengo una biblioteca de componentes, con una aplicación CRA de ejemplo para desarrollo

En el paquete.json de la aplicación CRA tuve que modificar reaccionar y reaccionar-dom para "tomar prestado" del paquete.json del componente raíz

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

Esto fue mega frustrante, espero que esto pueda ayudar a alguien más. Gracias a @chulanovskyi y @theKashey por sus sugerencias también.

@ Paddy-Hamilton Siempre verifique su archivo de bloqueo después de una instalación. Me encontré con el mismo problema donde yarn estaba duplicando react-test-renderer . Con un poco de cirugía en su archivo de bloqueo, podría arreglarlos:

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"

Un yarn check ya te avisaría

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

luego deduplicarlo manualmente aplicando el siguiente parche:

-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:

Ahora tiene una versión única de react-test-renderer sin ningún alias resolutions o webpack .

Para cualquier problema relacionado con paquetes vinculados y create-react-app siga facebook/create-react-app#6207

Hay muchas formas de resolverlo, y las resoluciones de hilo generalmente no ayudarían; está más relacionado con la "herramienta de construcción"

  • para el uso del paquete web aliases - solo alias "duro" todo se agacha como react a un solo archivo
  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'))
});
  • para broma usa moduleNameMapper
"jest": {
    "moduleNameMapper": {
      "^react$": "<rootDir>/node_modules/$1",
    },

Esto lo hizo por mí.

@ajcrews
¡Gracias! ¡Funciona brillantemente para mí!

Hice un pequeño caso de prueba con una configuración mínima usando reaccionar 16.8.6, electron-webpack y RHL. En particular, cuando ocurre este error, todo el navegador (en esta configuración, electron) comienza a consumir una gran cantidad de tiempo de CPU)

https://github.com/PerfectionCSGO/reeee

He estado golpeando mi cabeza sobre este problema durante 3 días. Originalmente pensé que RHL era el problema, pero eliminarlo por completo de este proyecto no resolverá el problema.

npm ls react devuelve solo un resultado. Me aseguré de que la solución anterior se aplique con las últimas versiones + alias de paquete web.

El código funcionará en una caja de arena.

En un paquete web/sitio web simple, el código funcionará sin problemas. Sin embargo, con electron-webpack este problema persiste.

  "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"
  }

Espero que alguien pueda darme una pista...

Cuando reemplace react-l18next con mobx-react-lite y use el observador, causará el mismo efecto.

Con respecto a mi problema, lo resolví dándole un codazo a electron-webpack y opté por una solución de electrones más "pura". Supongo que es una cadena de herramientas utilizada en webpack o babel que es incompatible.

Encontré este problema solo en producción. Ninguna de las soluciones propuestas aquí ayudó.
Mi caso de uso fue una aplicación de terceros que se carga como un widget en otro sitio web.
Cuando el sitio se cargó por primera vez con el widget, todo funcionó bien, pero cuando el usuario navegó a una página diferente y regresó a la página con el widget, recibí el error de enlace.

Tenga en cuenta que el error solo ocurre cuando la navegación no provoca una recarga de la página.

Pasé horas tratando de averiguar cuál era el problema. Finalmente, el problema estaba en el fragmento de código que carga el paquete de la aplicación. En el cambio de página, el paquete podría cargarse varias veces, lo que provocó, supongo, varias instancias de React en el mismo espacio de nombres.

Lo arreglé comprobando si el script ya se había cargado.
Primero exporté mi biblioteca al espacio de nombres global usando la configuración de 'biblioteca' de Webpack:

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

Y luego, en el script de carga, verifiqué si la biblioteca existe o no:

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);
}

Puede ser un caso de uso muy específico, pero espero que esto pueda ayudar a alguien más.

Así que tenemos una aplicación React principal que aprovecha el paquete web.
Estamos tratando de crear una pequeña biblioteca React que use ganchos, hemos intentado intercambiar paquetes (parcel, pure babel, webpack).
Al probar la implementación de nuestro paquete web, marcamos react y react-dom como externos, por lo que no los incluiremos en nuestro paquete.
Todavía obtenemos la misma excepción de ganchos cuando usamos el enlace npm.

La creación de un enlace simbólico a la reacción de la aplicación principal funciona, pero no es un gran flujo de trabajo de desarrollo.

Me está costando descubrir la causa subyacente del problema. ¿Qué está produciendo una instancia de React duplicada?

Hola @adriene-orange, puedes encontrar mi publicación https://github.com/facebook/react/issues/13991#issuecomment -472740798 para obtener más explicaciones.

Las instancias múltiples causadas por el enlace npm se deben a que el nodo de forma predeterminada buscará el módulo en node_modules de la carpeta principal si no puede encontrarlo en su paquete.

La solución más simple y mejor que encontramos para esto es en la configuración del paquete web (u otras herramientas) de su paquete de entrada, hay algo como resolve.modules para establecer manualmente las rutas y ordenar las rutas que buscará el paquete web para los módulos. Exp., resolve: { modules: [path.resolve(PACKAGE_ROOT, 'node_modules'), 'node_modules'] } , obligará a webpack a encontrar módulos en el node_module de la raíz del paquete de entrada primero. Si no puede encontrar el módulo en la raíz, búsquelo en la carpeta relativa node_modules...

Así que tenemos una aplicación React principal que aprovecha el paquete web.
Estamos tratando de crear una pequeña biblioteca React que use ganchos, hemos intentado intercambiar paquetes (parcel, pure babel, webpack).
Al probar la implementación de nuestro paquete web, marcamos react y react-dom como externos, por lo que no los incluiremos en nuestro paquete.
Todavía obtenemos la misma excepción de ganchos cuando usamos el enlace npm.

La creación de un enlace simbólico a la reacción de la aplicación principal funciona, pero no es un gran flujo de trabajo de desarrollo.

Me está costando descubrir la causa subyacente del problema. ¿Qué está produciendo una instancia de React duplicada?

hola me sale este error

Violación invariable: Llamada de gancho no válida. Los ganchos solo se pueden llamar dentro del cuerpo de un componente de función. Esto podría suceder por una de las siguientes razones:
1. Es posible que tenga versiones que no coincidan de React y el renderizador (como React DOM)
2. Podrías estar rompiendo las Reglas de los Hooks
3. Es posible que tenga más de una copia de React en la misma aplicación
Consulte https://fb.me/react-invalid-hook-call para obtener consejos sobre cómo depurar y solucionar este problema.

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

Código de muestra https://stackblitz.com/edit/react-mbze9q

Cuando intento acceder a esta función dentro de los casos de prueba, obtengo el error anterior

@abhishekguru Está llamando al gancho fuera de un componente aquí en su prueba:

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);
});

Como indica el error, los ganchos solo se pueden llamar desde otro gancho o desde dentro de un componente. En su caso, podría crear un componente para su prueba y renderizar ese componente que usa el gancho si lo desea.

Enchufe desvergonzado

@abhishekguru si tiene un enlace genérico utilizado entre varios componentes y desea probarlo independientemente de cualquier componente en particular, podría considerar usar react-hooks-testing-library .

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);
});

Quería intervenir aquí porque solo tuvimos problemas con SSR. Borramos los require.cache del nodo en los cambios de archivo. Esto efectivamente proporciona una recarga en caliente en el servidor. Borrar el require.cache del nodo causará problemas con las bibliotecas que necesitan tener una sola copia. Aquí está nuestra solución:

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]
  })

Nuestra función isSingleton contiene la lista de bibliotecas que deben tener una sola copia. Una buena regla general es cualquier biblioteca que deba definirse en peerDependencies

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

También tuve el mismo problema y para mí

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

también devolvió true , probé todas las sugerencias dadas pero nada funcionó. Finalmente resultó que:

Webpack agrega una etiqueta de secuencia de comandos con bundle.js en index.html automáticamente. Mi problema era porque estaba agregando bundle.js en index.html explícitamente , lo que solía funcionar bien antes de los ganchos.

Para mí, el problema fue después de la actualización de babel 7, no había versiones separadas con npm ls react. eliminando
"react-hot-loader/babel" de .babelrc solucionó el problema temporalmente.

Intenté todas las soluciones anteriores, pero aún recibí el error.
Eventualmente, descubrí que fue causado por el paquete why-did-you-update , y hay un problema relacionado con él. Solo una pista para cualquiera que use un paquete similar que modifique React.

Pude arreglar esto en un escenario de react-native + Yarn Workspaces .


En raíz package.json

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

Esto evita que se levante el código react-native (como se necesita para reaccionar nativo), mientras se sigue levantando react , por lo que todos los módulos compartidos usan la misma reacción.


En los 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
  ]
}

La configuración de metro le permite al empaquetador saber dónde está todo.

Encontré una manera de resolver el problema para las personas que están desarrollando localmente un paquete npm, por ejemplo, y están tratando de probarlo localmente cargando su paquete usando el enlace npm en algún tipo de aplicación de ejemplo.

Cambié de la aplicación de ejemplo (forma original de probar el componente) a Storybook . Al usar el libro de cuentos en el proyecto, no cargará React dos veces, ya que usará el mismo que está usando el componente. Mientras usaba el enlace npm, tuve problemas con los ganchos y React se cargó dos veces, y tampoco pude hacer que ninguna de las soluciones anteriores funcionara. Así que Storybook resolvió mi problema y ahora tengo una manera de probar mi componente a través de múltiples escenarios y al mismo tiempo crear documentación interactiva para él.

Compartiendo mi experiencia con esto, lo resolvió para nuestro proyecto mediante el uso de componentes externos del paquete web para que la biblioteca de componentes excluya react y react-dom de la compilación.

Recién estamos comenzando con React. En mi caso, estamos comenzando con Lerna monorepo con el paquete de biblioteca de componentes de Neutrino y el paquete de cliente de aplicación web de Neutrino. La aplicación web consume el producto de compilación de la biblioteca de componentes vinculados. Después de experimentar un poco y obtener true para la misma instancia de React, busqué una forma de excluir react y react-dom de la compilación de la biblioteca de componentes.

Parece una solución de patrón de diseño común para las bibliotecas de componentes del paquete web, por lo que en la biblioteca de componentes que he agregado a la configuración del paquete web:

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

No necesitaba poner una etiqueta de secuencia de comandos global en el paquete de la aplicación web para react y react-dom . Supongo que Webpack los proporciona a la biblioteca de componentes en su implementación require la misma manera que lo proporciona a la aplicación web.

otra causa de este error es la configuración incorrecta de Route de React Router,

Esto falla :

<Route render={MyHookedComponent}/>

, pero esto tiene éxito :

<Route component={MyHookedComponent}/>

P.ej. necesita usar component no render . Este es un error fácil de cometer ya que render generalmente funciona bien con componentes basados ​​en clases.

Estaba trabajando en biolerplate y quería publicarlo en npm, y desarrollarlo con la ayuda de npm link Funcionaba correctamente, pero después de un tiempo comenzó a dar errores Invalid Hook call warning .
Intenté usar el enlace npm ../myapp/node_modules/react pero no resuelve mi problema,
Y comparado con React1 === React2 es cierto, así como con npm ls react también hecho, muestra solo un paquete.

Y tampoco estoy usando el paquete web, solo estoy agregando una capa fuera de create-react-app para que no pueda obligar a mi aplicación a usar el módulo de reacción instalado localmente.
Atascado con él desde los últimos 3 días._

Igual que @hnagarkoti .

Experimenté esta advertencia durante la representación del lado del servidor (SSR) porque estaba usando una versión anterior de react-apollo así que solo quería dejar este enlace aquí para ayudar al próximo pobre que se encuentre con este problema:

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

En resumen, getDataFromTree no admite ganchos de reacción hasta la versión [email protected] .

Tuve el mismo problema y lo resolví agregando:

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

a la propiedad resolve en la configuración del paquete web de mi aplicación principal.

Obviamente, fue mi error usar dos copias de React, pero estoy de acuerdo en que sería genial si el mensaje de error fuera mejor. Creo que esto es tal vez similar a: # 2402

¿Alguna sugerencia para hacer esto con create-react-app?

^ Ok, la solución que busqué para resolver esto para create-react-app es usar react-app-rewired y customize-cra.

Aquí está mi config-overrides.js:

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

const path = require('path'); 

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

Proyecto de ejemplo: https://github.com/dwjohnston/material-ui-hooks-issue/tree/master

En nuestro equipo, tenemos un componente de navegación universal que funciona en decenas de aplicaciones, todas estas aplicaciones provienen de reaccionar 15.0.0 a reaccionar 16.8.0, para permitir la navegación implementada por encima de los ganchos, tenemos que agruparla con una última reacción

En este caso, tener varias instancias de reaccionar es un requisito fundamental para nosotros, me gustaría saber si el equipo oficial de reaccionar está dispuesto a resolver este problema en el futuro.

@dwjohnston, mi solución alternativa para create-react-app fue crear una configuración de paquete web para el desarrollo. create-react-app usa internamente webpack, webpack-dev-server y babel-loader, por lo que crear una configuración de paquete web solo para el desarrollo no fue tan malo porque las dependencias ya están implícitamente allí, pero todavía hay una buena cantidad de gastos generales para obtener el funcionamiento correctamente.

Tengo un problema en create-react-app : https://github.com/facebook/create-react-app/issues/6953 para agregar soporte webpack alias o similar.

👋 Si alguien también está usando create-react-app y experimenta este problema, ¿podría darle un pulgar hacia arriba a ese problema?

@ricokahler - Gracias por señalarlo. Me alegra ver que no soy la única persona con este problema, también lo he encontrado con el contexto.

¿Hay algún recurso que conozca que discuta más este tema?

Si está en mi bote, ha agregado un paquete de componentes de reacción desde un directorio local, y ahora lo compila e instala automáticamente, junto con su propia copia de node_modules (porque usa el enlace npm para hacer esto), dando su aplicación 2 copias o Reaccionar ahora.

Lo solucioné eliminando node_modules//node_modules antes de ejecutar la aplicación. Para hacer esto automáticamente:

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

También me enfrenté a esto cuando hacía SSR.
Si usa Lerna para probar localmente su biblioteca React, puede agregar "react/react-dom/react-router" como peerDependencies en su biblioteca, pero no debe agregarlas como devDependencies. (esto hace que se duplique)
Puede usar node --preserve-symlinks para que pueda buscar en el repositorio principal que instala las dependencias de pares.
Para broma, debe agregar la ruta del repositorio principal a la opción "jest.moduleDirectories" para que Jest pueda resolverlos

@apieceofbart funciona para mí, ¡gracias!

Me encontré con este error al cargar componentes React externos, por ejemplo, con módulos JS. Están completamente fuera del proyecto, cargados con importación dinámica () (bueno, jsonp para más soporte). Para solucionar el problema, pasamos/inyectamos React como una propiedad a cada módulo. Esto funciona, pero cada módulo depende de la aplicación React que lo contiene. Estamos tratando de eliminar las dependencias.

Como han mencionado otros, esta propiedad elimina React como utilizable para cualquier tipo de micro front-end. El problema es que existe este efecto secundario de crear un estado global en el tiempo de ejecución de JS al importar React para usarlo como biblioteca.

Entiendo que para casos de uso simples, tener ese efecto secundario significa que React es "más fácil de usar". Pero cuando una página web se compone de varios scripts de varios pasos de paquete, uno de ellos debería poder configurar React (hacer ese efecto secundario explícitamente) y los otros simplemente pueden llamar a funciones de biblioteca.

Todavía tengo un problema con react-bootstrap: # https://github.com/react-bootstrap/react-bootstrap/issues/3965

Para cualquier otra persona que se haya quedado atrapada tratando de hacer una biblioteca para React, intente https://github.com/whitecolor/yalc , funciona mucho mejor que los enlaces simbólicos.

@mpeyper funciona bien. Gracias

@apieceofbart Eso funcionó para mí. Gracias por la sugerencia. 👍

Para mí, este problema se produjo cuando navegué al directorio de mi proyecto en PowerShell y no puse en mayúscula un nombre de directorio en la ruta. Creé el proyecto en usuarios/…/… en lugar de Usuarios/…/...
El problema se resolvió cuando solucioné los errores de mayúsculas y recreé el proyecto.

Para mí, haciendo:

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

Se arregló la mayor parte pero no fue suficiente, seguí recibiendo el error hooks can only be called inside the body of a function component .

Resulta que fue porque algunos de los componentes de mi biblioteca se exportaron así:

export default Radium(withTranslation()(MyComponent))

:X:

Donde withTranslation es el HOC de react-i18next y Radium es el HOC de Radium.

Y exportándolos así:

export default withTranslation()(Radium(MyComponent))

:heavy_check_mark:
Arreglado todo.

Tenga en cuenta que react-i18next estaba en la versión 10 que usa React Hooks

@mikeaustin Estamos teniendo el mismo problema. ¿Tiene algún ejemplo de "pasar/inyectar React como una propiedad a cada módulo"?

Todavía tengo este problema, probé todos los pasos:

  • espacios de trabajo de hilo (a través de lerna)
  • verificado si hay una dependencia de reacción, sí

Algunas cosas que pueden tener impacto:

  • usando webpack con libraryTarget
  • usando mecanografiado
$ npm ls react-dom
/xxx
└── [email protected]

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

paquete raíz.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 Tuve el mismo problema y me funcionó, gracias.

Agregue "prestart" en su paquete.json como a continuación:

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

Tuve este problema y no se debió a múltiples versiones de react / react-dom
En las herramientas personalizadas que uso, el caché requerido se estaba borrando (para un propósito fuera de esta discusión), por ejemplo:

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

Entonces, para la gente, si está haciendo algo como esto, afectará a los React Hooks, así que evítelo si puede.

Tuve el mismo problema y lo resolví agregando:

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

a la propiedad resolve en la configuración del paquete web de mi aplicación principal.

Obviamente, fue mi error usar dos copias de React, pero estoy de acuerdo en que sería genial si el mensaje de error fuera mejor. Creo que esto es tal vez similar a: # 2402

Para cualquiera que use Parcel, si dist es donde están sus archivos compilados, debe agregar:

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

A su package.json y luego todavía puede link (npm o hilo) la biblioteca para desarrollo/prueba local.

@mikeaustin Estamos teniendo el mismo problema. ¿Tiene algún ejemplo de "pasar/inyectar React como una propiedad a cada módulo"?

Puede usar React Context para pasar "React" en sí mismo y crear un HoC para inyectar la propiedad en cada componente. Puede pasar cualquier cosa en api como api.React, pero se vuelve un poco complicado envolver HoC alrededor de esos componentes (porque ahora solo están disponibles dentro de un componente, no disponibles para exportar).

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

Dediqué un par de horas a esto, si cambiar el código fuente para modificar el mensaje de error y agregarle más información no es fácil y necesita más tiempo, al menos agregue esta nota en el documento ,

_p.s: reaccionar tiene una gran documentación, pero creo que esa página necesita revisión._

@OliverRadini

Pude arreglar esto actualizando react-hot-loader a ^4.6.0

Maaan, eso lo arregló.
@gaearon @theKashey ¿Qué tal agregar esto a https://reactjs.org/warnings/invalid-hook-call-warning.html para que las personas no pierdan el tiempo debido a una versión anterior de react-hot-loader ?

Pensé que ya está bastante bien documentado en una docena de números.

Hola, estoy usando React tanto en una aplicación como en una biblioteca . Yo uso la biblioteca dentro de la aplicación. Logré solucionar el problema de las dos instancias de reacción usando:

En la configuración del paquete web de la aplicación :

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

En la configuración del paquete web de la biblioteca

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

Así que me encuentro con un problema al llamar ganchos desde un archivo no transpilado (* .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;

¿Algún consejo, suponiendo que no sea "Moverlo al archivo JSX y transpilar"?

Nada parece funcionar para mí, estoy usando una combinación de estímulo y reacción, tengo una aplicación híbrida, comencé a usar ganchos y falló tan pronto como comencé a agregar turboenlaces :(

Editar: por ahora resolví mi problema agregando data-turbolinks-track="reload" data-turbolinks-eval="false" a las etiquetas de script que estoy usando, así que debería hacerlo por ahora

tengo la misma pregunta, después de 4 horas, me dijeron que era jenkins util que faltaba transformar los archivos .babelrc al servidor。。。

¿Por qué esto crearía el error?

$ 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 };

Por favor, compruebe cuál es su versión de react-dom.

$ npm ls reaccionar-dom
[email protected] /mnt/g/desarrollo/javascript/pow-vehmain
└── [email protected]

Me enfrenté a esto cuando exporté un connect(mapStateToProps)(MyComponent) de la biblioteca y usé esa biblioteca en mi aplicación CRA.

No, este fue mi gran error. La rutina que llamó a esto usó react-router-dom y usó el render prop en lugar del componente.

¿Alguno de ustedes ha tenido el mismo problema pero con Gatsby?

Obtengo el siguiente resultado después de 'npm ls react':
image

y 'npm ls react-dom'
image

Al principio, pensé que había instalado accidentalmente reaccionar globalmente, después de desinstalarlo globalmente, nada cambió. Luego, traté de crear un proyecto completamente nuevo en un directorio diferente, 'gatsby new random-name' y agregué una pequeña función (agregar comentarios, siguiendo a https://www.youtube.com/watch?v=asrdFuAxPaU&feature=youtu .be) a gatsby-starter-default para probar si el error se reproduciría. Bueno, para mi disgusto, ¡lo hizo!

Todos y cada uno de los consejos serían bien recibidos por una plebe frustrada.

Todavía estoy enfrentando este problema en el libro de cuentos. ¿Esta salida de npm ls es correcta o no?
imageimage

En mi caso, el problema fue causado por el módulo why-did-you-update .

Utilice el espacio de trabajo y lerna monorepo y levante el paquete. eso resolverá el problema.

estamos teniendo el mismo problema con SSR. parece funcionar configurando externals: [“react”] en nuestra configuración de paquete web y luego cargando manualmente react/umd/react.development.js . Sin embargo, esto es un dolor y me encantaría encontrar una manera más simple.

Ok, espero que esto ayude a alguien. Estábamos cargando el paquete web runtime.js varias veces accidentalmente, lo que provocó que existieran varias copias de React. Asegúrese de cargar el runtimeChunk (runtime.js) solo una vez.

Si tiene el problema con sus pruebas de Jest como yo, esto es lo que parece solucionarlo.
Agrega esto en tu jest.config.js

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

Sería bueno si este error al menos señalara el archivo donde está sucediendo. Accidentalmente llamé a un enlace en una función normal y fue difícil de depurar.

Encontré otra causa del problema y la solución.

Mi entorno es electron y webpack pero esto también podría ayudar a las personas que no son electrónicas. Pasé días dolorosos tratando de resolver por qué aparece este mensaje de error después de actualizar a React 16.9 (y React DOM 16.9).

En mi caso parecía que tenía dos Reacts en la aplicación, pero no pude encontrar dos bibliotecas físicas en node_modules, ni siquiera usando npm ls react . Incluso usé webpack-bundle-analyzer para ver qué hay dentro del paquete.

Eventualmente, descubrí que no tengo dos reacciones físicamente en el proyecto, pero React y React DOM fueron referenciados/cargados dos veces en el archivo HTML . Esto se puede verificar fácilmente agregando, por ejemplo console.log("React load") a index.js de la biblioteca React.

La fuente real estaba conectada a electron-webpack . react y react-dom no se marcaron como externos, por lo tanto, se cargaron en el paquete y más tarde desde node_modules debido a la necesidad de utilizarlos en algún otro módulo.

La solución fue tan simple como agregar estas líneas a webpack.renderer.config.js :

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

De acuerdo, entonces si alguien aquí usa paquete.js, por alguna extraña razón pude salirme con la siguiente importación: import React from 'React'; y una vez que comencé a usar ganchos de reacción, obtuve el error de violación invariable sin darme cuenta de que era porque estaba importando incorrectamente usando from 'React' en lugar de from 'react' . ¡Vaya!

¿Alguno de ustedes ha tenido el mismo problema pero con Gatsby?

Obtengo el siguiente resultado después de 'npm ls react':
image

y 'npm ls react-dom'
image

Al principio, pensé que había instalado accidentalmente reaccionar globalmente, después de desinstalarlo globalmente, nada cambió. Luego, traté de crear un proyecto completamente nuevo en un directorio diferente, 'gatsby new random-name' y agregué una pequeña función (agregar comentarios, siguiendo a https://www.youtube.com/watch?v=asrdFuAxPaU&feature=youtu .be) a gatsby-starter-default para probar si el error se reproduciría. Bueno, para mi disgusto, ¡lo hizo!

Todos y cada uno de los consejos serían bien recibidos por una plebe frustrada.

Sí, me he encontrado con el mismo problema que tú. He seguido los consejos aquí... ,

// 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);

Agregué React2 al archivo de índice en las páginas. Devuelve falso.

Deduplicado significa que npm debería haber deduplicado la dependencia ver aquí...

¡No es necesario instalar el mismo paquete dos veces! Solo está referenciado.

Además, mueve los paquetes "arriba del árbol" (aplana el árbol). Esto tiene mucho sentido ya que, de lo contrario, un paquete tendría que buscar en los node_modules de algún otro paquete (lo que sería un poco complicado) y ayuda a simplificar las dependencias.

Puede validar esto, ya que cada paquete en su gráfico de dependencia que dice deduplicado, se puede encontrar al menos una vez más en el gráfico, generalmente en un "nivel superior".

Aunque evidentemente la desduplicación no ha funcionado.

¿Qué has probado?

Recibo este error cuando intento compilar con NextJS. Algunos componentes usan material-ui y el problema desaparece si los elimino. No uso componentes con estilo. Intenté eliminar node_modules, etc. sin suerte. Intenté agregar alias y resoluciones para react en mi archivo next.config.js y package.json sin suerte. Estoy usando react 16.8.6, react-dom 16.8.6 y next 9.0.4. npm ls dice que solo hay uno de cada. No estoy usando ningún enlace npm.

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

Codesandbox está aquí: 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

El error está aquí: https://gist.github.com/dancancro/2dfafb053aaaedfade406fd4f67eb68a
... renderizar -> renderToString -> ReactDOMServerRenderer.read -> ReactDOMServerRenderer.render -> Object.WithStyles [como renderizado] ...

El gancho ofensivo es una llamada useStyles() en la línea 17428 del siguiente archivo en una función withStyles . Busque "clases var = useStyles (props)". El problema es con el código generado por nextjs. El código que escribí no usa withStyles ni ganchos ni funciones que comiencen con "use*"

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

ACTUALIZACIÓN: eliminar esto de mi next.config.js resolvió el problema:

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

Descubrí una solución eliminando react y react-dom de la carpeta node_modules #$ de mi paquete vinculado.

Estoy en el mismo barco que muchos de ustedes. Tengo un paquete de biblioteca en el que estoy trabajando localmente y no quiero pasar por la molestia de publicarlo cada vez que necesito ver cambios en mi paquete de aplicación. Lo vinculé y comencé a recibir este error.

Aquí está la solución:

  • Paquete A: su paquete de código de biblioteca ha sido npm link 'd
  • Paquete B: su paquete de código de aplicación. Tiene un enlace simbólico en su carpeta node_modules para el paquete A
  1. Paquete de compilación A. La mina genera sus activos en dist/ , incluidos sus node_modules
  2. En la carpeta node_modules distribuida del paquete A, elimine react y react-dom
  3. ???
  4. ¡Ganancia!

Tenga en cuenta que había instalado la misma versión de React en ambos paquetes. Tendrá que reiniciar cualquier proceso en ejecución.

Quitar why-did-you-update incompatible funciona para mí. (https://github.com/maicki/por-que-actualizaste/issues/52)

incompatible ¿por qué actualizaste?

El uso de @bertho-zero puede usar las nuevas herramientas de desarrollo o mi gancho useWhyDidYouUpdate

@brunolemos Es genial pero más restrictivo porque tienes que ponerlo en cada componente.

La solución de @ dmart914 resolvió el problema por mí. Yo también tengo paquetes vinculados para poder probar mi biblioteca sin publicar un cambio... ¿alguien ha encontrado una solución para esto? No es una gran experiencia publicar una biblioteca de código abierto y tener que documentar la eliminación de paquetes NPM específicos para que los ganchos comiencen a funcionar mágicamente...

La solución para eliminar el módulo react del paquete vinculado no funciona si ese paquete tiene pruebas que requieren react (por ejemplo @testing-library/react o @testing-library/react-hooks ), por lo que parece que todavía necesitamos una mejor manera de manejar esto.

Mi solicitud consta de dos partes. La aplicación web principal y un módulo que se carga dinámicamente en la aplicación web. Tanto la aplicación web como el módulo utilizan React 16.9.0.
El módulo se carga en la aplicación web utilizando React.lazy() y la declaración de importación dinámica().
Cuando se carga el módulo, aparece el error "Llamada de gancho no válida".

En mi caso, dado que la aplicación principal y el módulo se construyen por separado, no se conocen entre sí y tendrán su propia copia de reaccionar. Intenté las siguientes sugerencias que se encuentran en el hilo, pero no resolví el problema.

  1. Agregar un alias en el archivo webpack.config del módulo que apunta a la reacción de la aplicación principal según lo sugerido por apieceofbart .
    alias: {
    reaccionar: ruta.resolve('../../node_modules/react')
    }

  2. Intenté señalar las dependencias de reacción en el paquete del módulo.json a la aplicación principal.
    "dependencias": {
    "react-dom": " archivo:../common/node_modules/react-dom ",
    "reaccionar": " archivo:../common/node_modules/react "
    }

Creo que reaccionar tiene que admitir la ejecución de varias copias cuando se trata de módulos cargados dinámicamente.

Basado en algunas de las respuestas anteriores, esto es lo que funcionó para mí:

  1. Se agregó lo siguiente a config/webpack.config.js
externals: {
  react: {
    root: 'React',
    commonjs2: 'react',
    commonjs: 'react',
    amd: 'react'
  },
  'react-dom': {
    root: 'ReactDOM',
    commonjs2: 'react-dom',
    commonjs: 'react-dom',
    amd: 'react-dom'
  }
}
  1. Editado package.json
"devDependencies" : {
  ...
  "react": "^16.9.0",
  "react-dom": "^16.9.0",
}
"peerDependencies": {
  "react": "^16.9.0",
  "react-dom": "^16.9.0"
}
  1. Editado 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>
...

Después de eso, pude ejecutar ganchos en mi biblioteca usando React cargado desde CDN, mientras que Jest aún cargaba la copia de reacción desde node_modules (instalada desde devDependencies).

Espero que ayude

Me enfrenté a este problema cuando trato de cambiar mi componente de funcional a componente con clase y también recibo este error, así que aquí está mi solución con respecto a este error, espero que también ayude en su caso.

intente usar un componente de orden superior en este caso

importar React desde 'react';
importar PropTypes desde 'prop-types';
importar {withStyles} desde '@material-ui/styles';
botón de importación desde '@material-ui/core/Button';

const estilos = tema => ({
raíz: {
fondo: 'gradiente lineal (45 grados, #FE6B8B 30%, #FF8E53 90%)',
borde: 0,
bordeRadio: 3,
sombra de caja: '0 3px 5px 2px rgba(255, 105, 135, .3)',
color blanco',
altura: 48,
relleno: '0 30px',
},
});

clase HigherOrderComponent extiende React.Component {

hacer(){
const {clases} = this.props;
regreso (
componente de orden superior
);
}
}

ComponenteDeOrdenSuperior.propTypes = {
clases: PropTypes.object.isRequired,
};

exportar por defecto withStyles(styles)(HigherOrderComponent);

Estoy usando Yarn y solucioné esto forzando la resolución en mi package.json :

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

¿Agregó en el paquete principal o secundario?

Basado en algunas de las respuestas anteriores, esto es lo que funcionó para mí:

  1. Se agregó lo siguiente a config/webpack.config.js
externals: {
  react: {
    root: 'React',
    commonjs2: 'react',
    commonjs: 'react',
    amd: 'react'
  },
  'react-dom': {
    root: 'ReactDOM',
    commonjs2: 'react-dom',
    commonjs: 'react-dom',
    amd: 'react-dom'
  }
}
  1. Editado package.json
"devDependencies" : {
  ...
  "react": "^16.9.0",
  "react-dom": "^16.9.0",
}
"peerDependencies": {
  "react": "^16.9.0",
  "react-dom": "^16.9.0"
}
  1. Editado 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>
...

Después de eso, pude ejecutar ganchos en mi biblioteca usando React cargado desde CDN, mientras que Jest aún cargaba la copia de reacción desde node_modules (instalada desde devDependencies).

Espero que ayude

Sin ofender, pero es preocupante que se tengan que seguir soluciones como esta. He estado tratando de resolver este error durante los últimos días sin depender de tales hacks.

Estoy trabajando en una biblioteca reutilizable que contiene componentes que usan ganchos. Necesito probarlos en proyectos reales antes de publicarlos. La única solución para esto es usar yarn|npm link . Agrupo la biblioteca mediante el paquete acumulativo y puedo verificar que el paquete no contiene una versión de reaccionar. Cuando agrego (paquete web) la aplicación que hace uso de la biblioteca, aparece el error/problema. Esto sucede con aplicaciones básicas de create-react-app y next.js también. Ambos marcos usan webpack en segundo plano.

¿Alguien ha encontrado ya una solución sostenible?

Al deshacerme npm|yarn link completo, pude resolver el problema. En cambio, uso esta hermosa biblioteca, que es independiente de la estructura de su proyecto. También le permite seguir usando webpack como su paquete, por lo que no tiene que declarar _react_ y _react-dom_ como external o alias . Desafortunadamente, introduce algunos directorios nuevos y archivos de bloqueo en el proyecto, pero bueno, funciona... localmente e incluso dentro de nuestros contenedores docker.

Tal vez esto será en la lista un poco útil:

Enlace

@GabrielBB gracias, es trabajo para mí

@ dmart914 gracias! Hasta ahora, la única solución que funciona para mí :)

Actualmente recibe la advertencia React Invalid Hook Call cuando se usa una configuración mínima y sencilla.

Este componente de función:

  1. Utiliza la misma versión para React y ReactDOM.
  2. Sigue las Reglas de Hooks.
  3. Solo tiene una copia de React.

__Dependencias__
[email protected]
[email protected]
paquete [email protected]
[email protected]

Y ejecutando webpack test.js -o main.js para construir.

Espero que este archivo:

  • Renderiza la caja.

    • Pausa el depurador antes de llamar a React.useState .

    • Cree un valor booleano test y actualice la devolución de llamada updateTest .

    • Lanza el error React.

    • Al renderizar, realice las devoluciones de llamada React.useEffect .

    • Lanza el error React.

¿Estoy haciendo algo mal o está pasando algo más?

// 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();

Se olvidó de crear realmente un elemento. Está invocando sincrónicamente Item() antes de llegar a la llamada ReactDOM.render . Tienes que pasar el(Item) .

¡Cierto! Gracias por la información.

Estoy en una situación similar a algunos de los otros comentaristas. Estoy usando webpack para transpilar algunos componentes de reacción (algunos de los cuales usan ganchos) y coloco el código transpilado en una carpeta lib . Agregué reaccionar al campo externals de la configuración del paquete web para que no se incluya con el código del componente. Me gustaría usar estos componentes en dos proyectos separados: estos componentes son comunes entre ellos y, por lo tanto, nos gustaría desarrollarlos en un solo lugar y que las actualizaciones se reflejen en ambas aplicaciones.

Si la dependencia se agrega usando common-components: file:../../common-components/lib en package.json, los componentes se cargan perfectamente; sin embargo, ejecutar webpack no actualiza los componentes de inmediato; en su lugar, debo ejecutar yarn upgrade common-components y luego reiniciar el servidor de desarrollo.

Si la dependencia se agrega usando common-components: link:../../common-components/lib , volver a ejecutar el paquete web actualizará los archivos en node_modules de la aplicación principal (ya que ahora está usando un enlace simbólico), pero recibo el error anterior de varias instancias de reaccionar. Supongo que ahora está usando la versión de reacción en la carpeta common-components/node_modules .

¿Hay alguna manera de usar enlaces simbólicos (es decir common-components: link:../../common-components/lib ), y al mismo tiempo asegurarse de que los componentes vinculados usen la reacción que se encuentra en la carpeta node_modules de la aplicación principal? Dado que planeo usar estos componentes en ambas aplicaciones, no puedo vincular el paquete de reacción de una de ellas a la biblioteca de componentes comunes y me gustaría evitar vincular las reacciones de las dos aplicaciones principales con la utilizada en el paquete de componentes comunes. He visto algunos comentarios que se refieren al campo resolve del paquete web que suena prometedor, pero no puedo hacerlo funcionar. ¡Cualquier ayuda sería muy apreciada!

editar: para cualquier persona interesada en nuestro caso de uso, terminamos cambiando el paso de compilación para simplemente copiar los archivos en los dos proyectos en los que se necesitan y evitar la transpilación por completo.

Una solución rápida sería no publicar el paquete, sino simplemente enviarlo a github e importarlo a su proyecto usando yarn add <git-url> .

Una solución rápida sería no publicar el paquete, sino simplemente enviarlo a github e importarlo a su proyecto usando yarn add <git-url> .

La razón por la que muchos de nosotros usamos el enlace npm y las rutas relativas del paquete npm es para desarrollar y probar el código sin tener que publicar cambios en NPM o GitHub antes de saber que funcionará.

Nos encontramos con este problema relacionado con https://github.com/facebook/react/issues/13972#issuecomment -447599035 en el sentido de que creo que esto también puede deberse a un servidor de nodo de Webpack. Nuestro caso de uso fue una prueba de integración que se ejecutaba dentro de Jest que ejecutaba webpack() programáticamente para construir el servidor antes de ejecutar las pruebas. El problema, creo, está relacionado con cómo ESM y CJS pueden existir al mismo tiempo.

Tome este ejemplo por ejemplo:

// 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>)

Lo que veo en una sesión de depuración es que podemos obtener dos instancias diferentes de React en la versión compilada de este archivo:

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

Donde
_react es del ESM import React from 'react' en este archivo
_react2 es del CJS var _react = _interopRequireDefault(require("react")); desde dentro de node_modules/@apollo/react-ssr/lib/react-ssr.cjs.js

Creo que esto hizo que la referencia a React no fuera igual en los dos lugares (archivo de procesamiento del servidor y dentro del paquete @apollo/react-ssr ) y, por lo tanto, provocó que se arrojara el error.

Descubrimos que esto probablemente se debió al uso programático de webpack() desde dentro de la prueba, y hemos refactorizado esas pruebas para que sean pruebas de un extremo a otro. La lección es para nosotros que si el problema ocurre solo en el código de prueba, es posible que tenga pruebas demasiado complicadas.

Logré resolverlo con hilo:

cd a myApp/node_modules/react y yarn link

luego en tu biblioteca, ejecuta yarn link react

Ahora su biblioteca está usando exactamente la misma versión de reacción que su aplicación principal

Traté de configurar reaccionar como una Dependencia de pares en mi lib pero luego la lib no se compilaría

¿Cómo se puede arreglar esto usando create-react-app sin expulsar o cambiar a yarn ?

Puede usar exactamente la misma técnica usando el enlace npm. No es necesario expulsar.

Vincular react no es la mejor idea cuando trabajas en múltiples proyectos con diferentes versiones.

@woles tienes toda la razón, pero en mi caso, resuelve mi problema de 'ganchos'. Espero que los desarrolladores de React presenten una mejor solución.

Hola,
Solucioné este error después de horas al darme cuenta de que accidentalmente usé el componente falsamente dentro del enrutador de reacción.

Mi aplicación funcionaba, pero en un componente no pude agregar useState en absoluto. la razón fue que usé el componente dentro del método de procesamiento de enrutadores de reacción sin la función de orden superior como esta:
<Route exact path="/path" render={ ComponentCausingTheErrorMesage }/>
cambiar a
<Route exact path="/path" component={ ComponentNowWorkingAgain }/>
lo arregló para mí

Estaba usando npm link entre una aplicación y un módulo en el que estaba trabajando activamente, y tuve que arreglarlo vinculando react y react-dom de la aplicación al módulo, luego vinculando el módulo a la aplicación:

en la aplicación:

  1. cd node_modules/react && npm link
  2. lo mismo por react-dom

en módulo:

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

en la aplicación:

  1. npm link [module-name]

Espero que esto ayude a alguien

Teníamos ganchos que funcionaban en el lado del cliente, pero recibíamos este error en SSR. Mi colega resolvió esto con lo siguiente en nuestra configuración de paquete web del lado del servidor:

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

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

Logré resolverlo con hilo:

cd a myApp/node_modules/react y yarn link

luego en tu biblioteca, ejecuta yarn link react

Ahora su biblioteca está usando exactamente la misma versión de reacción que su aplicación principal

Traté de configurar reaccionar como una Dependencia de pares en mi lib pero luego la lib no se compilaría

Esto funciona simplemente hermoso

Me encontré con este problema al usar electron-webpack, react y material-ui al mismo tiempo. Cuando trato de usar algo de material-ui, aparece este error (por ejemplo, intento usar el

Hola ZVER3D, intenta leer mi comentario anterior. ¡Espero eso ayude!

Estaba usando npm link entre una aplicación y un módulo en el que estaba trabajando activamente, y tuve que arreglarlo vinculando react y react-dom de la aplicación al módulo, luego vinculando el módulo a la aplicación:

en la aplicación:

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

2. same for `react-dom`

en módulo:

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

2. `npm link`

en la aplicación:

1. `npm link [module-name]`

Espero que esto ayude a alguien

Dulce bebé Moisés, esto me ayudó mucho. ¡Ni siquiera consideró que el problema fueran diferentes versiones de reaccionar! Estoy creando un componente localmente para publicarlo en NPM pero tengo un proyecto separado para probarlo localmente, usando el enlace npm. Obviamente (ahora) ambos están usando diferentes versiones de reaccionar. D'oh!

Hola ZVER3D, intenta leer mi comentario anterior. ¡Espero eso ayude!

Gracias por señalarme en la dirección correcta. Otra solución fue agregar la biblioteca ui, que estoy usando en "whiteListedModules". El único problema sería que tendría que hacerlo para todos los módulos que requieran reaccionar para compilar.
Entonces, en package.json escribí esto:

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

Estoy desarrollando una aplicación React utilizando el enfoque monorepo. Tengo una aplicación principal ( brush ) y un componente de biblioteca de reacción ( react-gbajs ).

Entonces, cuando intento renderizar mi componente react-gbajs , tengo este error sobre varias instancias de React. Si copio y pego el mismo código en brush no tengo ningún problema.
Seguí muchos enfoques para solucionarlo, pero ninguno de ellos lo resolvió (cambio de compilación en Webpack, espacio de trabajo de Yarn, enlace npm...)

Traté de depurar para verificar si realmente tengo dos copias de React (usando console.log(window.React1 === window.React2) del documento de React), ¡pero se evalúa como true !
(una solución MUY MALA que estoy usando ahora es pasar los ganchos como apoyo: <GBAEmulator useEffect={useEffect} /> ... pero realmente no quiero fusionarlos)

Alguien tiene alguna idea para arreglarlo?

Mi proyecto es de código abierto y estoy agregando este nuevo componente de biblioteca de reacción en esta rama: https://github.com/macabeus/klo-gba.js/blob/ac18f4d42b122c333622f502947135c2de217ce2/react-gbajs/src/index.js#L251 -L274

Hola a todos,

Tengo una aplicación (myApp) que usa como dependencia una biblioteca personalizada (myDepPackage). Ambos están usando webpack como herramienta de compilación y, por supuesto, estaba teniendo el mismo error. Ninguna de las soluciones anteriores funcionó para mí. Lo que hizo fue obligar al paquete web a NO incluir reaccionar en el paquete final de la biblioteca personalizada (myDepPackage). La única línea de configuración que tuve que agregar a la configuración del paquete web (de myDepPackage) es la siguiente:

externals: {
  react: "react",
},

Puede obtener más información sobre la opción "externos" aquí: https://webpack.js.org/configuration/externals/#externals

@tsevdos Muuuuchas gracias!!! ❤️
Resolvió mi problema que dije en el comentario anterior.

Para nosotros, el problema fue que tenemos una aplicación React integrable que se carga en la página desde un código abreviado de WordPress y se monta en un div con una ID aleatoria. En algunas páginas tenemos varias aplicaciones integradas y funcionaba bien hasta que empezamos a usar ganchos.

Solo se quejaría en las páginas que tienen varias aplicaciones integradas, por lo que la solución fue actualizar el código abreviado de WP para cargar el script con la compilación solo una vez.

Suena simple y obvio, ¡pero fue difícil de entender! Especialmente porque estaba haciendo eso y funcionaba bien hasta que agregamos ganchos.

Curiosamente, en algunas páginas tenemos otras aplicaciones (diferentes) que incrustamos y que también usan ganchos, y también cargan su propio script/compilación con React,... ¡pero luego funciona bien! El problema era cuando se cargaba exactamente la misma compilación más de una vez y usaban ganchos .

Lo que funcionó para mí fue una combinación de dos sugerencias de este tema.

Configuración del paquete web de la aplicación principal ( sugerencia de @apieceofbart )

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

Configuración del paquete web de dependencia ( sugerencia de @tsevdos )

  externals:
    react: 'react'
  }

Estaba teniendo este problema con html-webpack-plugin y estaba usando index.html como una configuración template a HtmlWebpackPlugin .

// 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>

Me di cuenta de que el complemento estaba inyectando <script type="text/javascript" src="main.js"></script> justo después <div id="root"></div> .

Entonces, cuando abrí la herramienta de desarrollo y generé html se veía así.

<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>

Para mí, eso estaba causando Invalid Hook Call Warning .

Pude eliminar la advertencia eliminando <script src="main.js"></script> como se muestra a continuación.

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

</html>

¡Espero que ayude a alguien que busca una solución!

Tenga en cuenta que las bibliotecas dependientes de React también pueden causar estos problemas. En mi caso, estaba usando diferentes versiones de @emotion/core y @emotion/styled .

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

Hola,

Una posible solución sin expulsar es mezclar la solución de configuración de alias del paquete web con las bibliotecas customize-cra y react-app-rewired . De esta manera, puede anular solo la configuración necesaria del paquete web para resolver el problema, creando un archivo config-overrides.js con:

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

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

Tuve este problema en un sitio de Gatsby, ejecuté npm install y actualicé a la última versión de Gatsby y lo arregló todo.

Si tiene un problema con la prueba de broma que ejecuta yarn or npm test (como yo) y está usando react-test-renderer , asegúrese de que react-test-renderer coincida con la misma versión de react Tu estas usando.

Ejemplo:

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

Ejecutar yarn add [email protected]

Tengo una librería y verifiqué todas las versiones de react y react-dom tanto en la librería como en los proyectos principales. son exactamente iguales pero no funcionaron.
Sin embargo, la solución @apieceofbart funcionó para mí.

@apieceofbart , me salvaste el día <3

Lo que funcionó para mí fue una combinación de dos sugerencias de este tema.

Configuración del paquete web de la aplicación principal ( sugerencia de @apieceofbart )

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

Configuración del paquete web de dependencia ( sugerencia de @tsevdos )

  externals:
    react: 'react'
  }

Aquí igual. Necesito hacer ambas correcciones para que funcione. Mi explicación es que la segunda configuración le dice a la dependencia que use una reacción externa con el nombre 'reaccionar', y la primera configuración apunta el nombre 'reaccionar' a la carpeta 'node_modules/react' en el repositorio principal. Por lo tanto, ambos son necesarios para que el puente de reacción funcione.

Aún así, parece que para algunas personas uno de ellos es suficiente, lo que realmente no entiendo.

Lo que funcionó para mí fue una combinación de dos sugerencias de este tema.
Configuración del paquete web de la aplicación principal ( sugerencia de @apieceofbart )

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

Configuración del paquete web de dependencia ( sugerencia de @tsevdos )

  externals:
    react: 'react'
  }

Aquí igual. Necesito hacer ambas correcciones para que funcione. Mi explicación es que la segunda configuración le dice a la dependencia que use una reacción externa con el nombre 'reaccionar', y la primera configuración apunta el nombre 'reaccionar' a la carpeta 'node_modules/react' en el repositorio principal. Por lo tanto, ambos son necesarios para que el puente de reacción funcione.

Aún así, parece que para algunas personas uno de ellos es suficiente, lo que realmente no entiendo.

¡El segundo elemento es importante!
Si se ignora, en el proceso de compilación, la reacción se exportará en conjunto, porque es una dependencia interna

mucho amor @apieceofbart !!!! Estaba a punto de patear mi escritorio a través de la pared

Por lo tanto, todavía no hay una solución para los microservicios. Tengo una aplicación raíz con reacción que requiere dinámicamente paquetes con otra reacción. No podemos simplemente usar la versión externa de reaccionar porque hay muchos equipos independientes con sus propias dependencias. Si los presionamos para que usen la misma versión externa, la mayoría de los proyectos obviamente fallarán y será imposible actualizar esta versión debido a que cada proyecto dependerá de esta versión.

¿Algunas ideas?

¿Existe una solución para usar ganchos de reacción junto con un enlace npm, que no requiera la expulsión de CRA?

@tchellenbach
puede usar craco para sobrescribir la configuración de CRA sin expulsar.
https://github.com/gsoft-inc/craco

Gracias a @tsevdos resolví mi problema e hice un tutorial sobre cómo crear un paquete React: https://youtu.be/esyS87NfBOw

Estaba teniendo este problema y la solución del paquete web no se aplicaba porque en su lugar estoy usando el paquete de paquetes. Pude solucionarlo especificando un alias en el paquete.json de mi aplicación principal que se veía así

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

Tengo problemas al tratar de usar mis componentes React (escritos en ganchos) en una aplicación de electrones en el mismo proyecto con un paquete json diferente. La estructura del archivo se ve así:

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

Ambos package.json incluyen react y react-dom en package.json pero son las mismas versiones y no veo que muestre dos instalaciones de reacción cuando hago npm ls react . ¿Algunas ideas?

EDITAR: ¡la solución de @ ewan-m funcionó!

Así que me encontré con un caso extraño, creo. Desafortunadamente, una biblioteca de terceros ha mezclado componentes funcionales y basados ​​en clases. Mis componentes en mi base de código son funcionales. Un componente basado en clases de la biblioteca actúa como un diseño que representa mi componente como un elemento secundario. Creo que esto es lo que está desencadenando el 'Error: llamada de enlace no válida'. ¿Cómo debo solucionar eso para usar ganchos? ¿Necesito convertir el mío en un componente de clase?

@GrandathePanda Mezclar clases y componentes funcionales no debería importar. Si una clase llama a un funcional, que llama a un gancho, no hay problema. Lo único que no puede hacer es llamar a un gancho directamente desde la clase.

De acuerdo, @JeremyGrieshop , todavía tengo que investigar un poco, si renderizo sin usar el componente de terceros, funciona bien, por lo que hay algún conflicto entre esa biblioteca y mi código. Si tuviera que adivinar que están usando una versión de reacción diferente, tal vez en su paquete.

De acuerdo, @JeremyGrieshop , todavía tengo que investigar un poco, si renderizo sin usar el componente de terceros, funciona bien, por lo que hay algún conflicto entre esa biblioteca y mi código. Si tuviera que adivinar que están usando una versión de reacción diferente, tal vez en su paquete.

Correcto, revisa npm ls react react-dom desde tu aplicación para ver si hay varias versiones. Es posible que la biblioteca de terceros tenga una dependencia con una versión específica.

@JeremyGrieshop Parece que mi aplicación usa 16.12.0 para reaccionar y dom y el tercero (elástica de búsqueda-ui) usa 16.8.0 para reaccionar y dom. Si estoy en lo correcto, el problema es que, dado que mi biblioteca de terceros 16.8.0 está procesando el componente creado con 16.12.0, ¿esto causará el problema? También son un lerna monorepo que potencialmente complica esto aún más después de leer todos los comentarios anteriores. El problema surge de un enlace useStyles creado en materialui, proporcionan un withStyles hoc para compatibilidad con versiones anteriores y creo que mientras tanto voy a ir por ese camino. Todos los cambios en webpack y/o el paquete json mencionado anteriormente realmente parecen una curita que es más probable que se rompa que simplemente hacer un hoc clásico mientras tanto, mientras los ganchos descubren cómo madurar frente a tantas objeciones de implementación diferentes.

@GrandathePanda En mi humilde opinión, sus opciones son (1) hacer que el tercero actualice su dependencia de reacción a 16.12, o que decida si tenerlo como una dependencia de pares es más adecuado que una dependencia; (2) Use 16.8 en su aplicación para que compartan las mismas versiones de lib; (3) Eliminar su copia de reaccionar con:

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

El comando anterior se puede colocar en una "preconstrucción" y "preinicio" en la parte "scripts" de su paquete.json (que es lo que estoy haciendo actualmente). La desventaja de (3), supongo, es si están usando algo obsoleto entre 16.8 y 16.12.

Hola a todos,

Tengo una aplicación (myApp) que usa como dependencia una biblioteca personalizada (myDepPackage). Ambos están usando webpack como herramienta de compilación y, por supuesto, estaba teniendo el mismo error. Ninguna de las soluciones anteriores funcionó para mí. Lo que hizo fue obligar al paquete web a NO incluir reaccionar en el paquete final de la biblioteca personalizada (myDepPackage). La única línea de configuración que tuve que agregar a la configuración del paquete web (de myDepPackage) es la siguiente:

externals: {
  react: "react",
},

Puede obtener más información sobre la opción "externos" aquí: https://webpack.js.org/configuration/externals/#externals

@tsevdos Te amo. Acabas de poner fin a unos días de intensa molestia. Gracias.

Hola a todos,

Estoy tratando de usar un gancho en un componente, este componente se exportará desde gatsby-browser.js .

¿Cuál es el comportamiento actual?

Estoy recibiendo este error:

Rechazo no manejado (Error): Llamada de gancho no válida. Los ganchos solo se pueden llamar dentro del cuerpo de un componente de función. Esto podría suceder por una de las siguientes razones:

  1. Es posible que tenga versiones que no coincidan de React y el renderizador (como React DOM)
  2. Podrías estar rompiendo las Reglas de los Hooks
  3. Es posible que tenga más de una copia de React en la misma aplicación
    Consulte https://fb.me/react-invalid-hook-call para obtener consejos sobre cómo depurar y solucionar este problema.

Este es un código de muestra:

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;

¿Cuál es el comportamiento esperado?

Hook debe ejecutarse sin errores, o deben proporcionarse mensajes de error útiles.

Las versiones de las dependencias react y react-dom son 16.12.0

@leejh3224 muchas gracias amigo! después de horas de búsqueda encontré esta respuesta, resolvió mi problema.
Acabo de cambiar la configuración de HtmlWebpackPlugin de
inject: true a inject: 'head' y los errores de reacción minimizados desaparecieron.

Creé una pregunta de stackoverflow con mi experiencia de tratar de hacer que esto funcione. ¿Sería posible, para aquellos que han logrado que esto funcione, echarle un vistazo y ofrecer algún consejo?

Estoy portando una aplicación jquery a React. Tengo una utilidad para exponer los componentes de React dentro de jQuery llamada asJqueryPlugin . Aquí está el archivo:

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.$)
}

La aplicación tiene muchos puntos de entrada en Webpack, y alrededor de 3 o 4 componentes están usando esta técnica ahora. Cuando los componentes se agrupan en diferentes paquetes de puntos de entrada, creo que ahí es cuando ocurre el problema.

Entonces, si tengo dos puntos de entrada en Webpack:

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

Luego, en cada uno de esos archivos, configuramos un Componente expuesto (cada uno usando ganchos):

// 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

Ahora, si incluyo ambas entradas en la misma página e intento representar ambos componentes a través del complemento jquery...

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

... Recibo este error de ganchos.

No estoy seguro de si esto ayuda a la conversación o no, pero al menos muestra un caso de uso de cómo un desarrollador (cuestionablemente) cuerdo podría meterse en una situación con múltiples instancias de reacción.

Eso me ayudó: https://github.com/facebook/react/issues/13991#issuecomment -554928373
Pero también tuve que eliminar react y react-dom de las dependencias y moverlos a dependencias del mismo nivel y desinstalar y reinstalar módulos de nodo.

Hola,
Leí la conversación y muchas publicaciones en la web y todavía estoy atascado con el error de múltiples instancias de reacción.
Empujo este repositorio para reproducir el error: https://github.com/jeromelegrand/dooliz-lib
Espero que alguien pueda ayudarme.
Gracias.

Me enfrento a este problema y no llego a ninguna parte con las soluciones anteriores.
En resumen: estoy muy seguro de que solo tengo una versión de reacción en ejecución, y obtengo el error al usar react-bootstrap, que probablemente no usa ganchos de forma incorrecta, porque nadie más tiene problemas.

Este error ocurre en un backend de node.js para mí.

__Lo que verifiqué sobre las versiones de reacción__

Tengo una configuración de hilo con espacios de trabajo, yarn list react o yarn list react-dom solo muestra una instancia.

Imprimí require cache para ver lo que se ha importado:

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

Lo ejecuto justo antes de extraer algo de react-bootstrap, lo que me provoca el error de enlace no válido, y registra:

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

Lo que parece confirmar que solo hay 1 versión de reacción cargada.

Finalmente, agregué esto a node_modules/react-dom/index.js

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

Y esto a 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'));

Que imprime SAME

¿Alguna idea de qué más puede ser esto?
También publicaré esto en el repositorio de react-bootstrap.

Así que estoy bastante seguro de que tener dos instancias de React no es el problema aquí. Creo que el problema es cuando hay dos reacciones _roots_. ¿Estás llamando a ReactDOM.render() varias veces en diferentes partes de la página? Si es así, creo que esto puede causar el problema. Creo que los ganchos "pertenecen" a una "raíz" en particular y se rompen cuando hay varios de ellos y los dos paquetes comparten un código común. Supongo que aquí...

... Yo creo que el tema es cuando hay dos react _roots_. ¿Estás llamando a ReactDOM.render() varias veces en diferentes partes de la página?

Gracias @timkindberg , esto finalmente me ayudó a resolverlo. Me di cuenta de que estoy usando react-tree-walker para hacer un renderizado inicial y obtener los datos requeridos antes de hacer el renderizado final con ReactDOMServer.renderToString

Eliminar rápidamente el uso de este paquete eliminó el error, y ahora tengo lo mismo trabajando con react-ssr-prepass , que en realidad ahora se recomienda en la página Léame de react-tree-walker

¡Así que de hecho fueron dos llamadas ReactDOM.render ! Por ahora, esta configuración con react-ssr-prepass funciona para mí, y cuando Suspense aterriza en react-dom/server, puedo cambiar a eso.

Estoy usando react-compare-image https://github.com/junkboy0315/react-compare-image en mi proyecto de Gutenberg pero tengo este problema extraño, aunque todo funciona cada vez que elimino el componente ReactCompareImage de la función de guardar. La función de edición funciona perfectamente pero el guardado no funciona.

Revisé https://reactjs.org/warnings/invalid-hook-call-warning.html y no creo que tenga ninguno de estos problemas.

Aquí está el archivo de función de guardado completo:

```importar Inspector desde "./inspector";
importar { Fragmento } de "reaccionar";
importar ReactCompareImage desde "react-compare-image";

/**

  • Dependencias de WordPress
    */
    constante {__} = wp.i18n;

const save = ({className, atributos}) => {

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>
);

};

exportar guardado predeterminado;
```
Screenshot 2020-02-19 at 4 11 52 PM

También me estoy encontrando con este problema. Tengo un resumen publicado en SO: https://stackoverflow.com/questions/60331304/next-js-with-typescript-invalid-hook-call-hooks-can-only-be-called-inside-of-t

También tengo un ejemplo reproducible mínimo: https://github.com/coler-j/shopify_playground

Mi aplicación principal es una aplicación create-react (no expulsada) que estaba importando una biblioteca compartida que también usaba React. Pude resolver esto por:

Uso de Rollup para empaquetar la biblioteca en lugar de webpack
Por alguna razón que aún tengo que resolver, el uso de elementos externos no eliminó React del paquete de la biblioteca.

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(),
    ],
  },
]

Instalar craco y usarlo para modificar el paquete web de la aplicación principal
craco.config.js

const path = require('path')

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

Gracias a @arminyahya por señalarme a Craco.

Estoy tratando de usar ganchos mientras cargo reaccionar desde un cdn. Este ejemplo (esta es la página html completa) da el error Hooks can only be called inside of the body of a function component cuando se llama a Example() . Eliminé todo, incluso ReactDOM, por lo que es difícil imaginar que podría tener varias copias de React. ¿Es esto simplemente imposible?

<!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 Eso es porque tienes CERO raíces de reacción. Necesitas renderizar tu aplicación. Sin embargo, esta sigue siendo una buena confirmación de que los ganchos se basan en (y están acoplados a) una raíz de reacción.

<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>

¡Gracias! En realidad, no fue la falta de una raíz de reacción, simplemente la eliminé para simplificar el error tanto como fuera posible, sino algo igualmente tonto: en lugar de <Example /> , solo escribí Example() . No es lo mismo, en absoluto. Gracias de nuevo.

Nada parece funcionar para mí. Estoy creando un componente para compartir y usar en otros proyectos, pero cuando se prueba localmente desde otro proyecto no funciona. Estoy usando Hooks con 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',
    }),
  ]}

¿Alguna sugerencia? Probé todas las sugerencias de viejas discusiones.
¡Gracias! :sonrisa:

Declaré un Settings.js de la siguiente manera:

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};

Lo importo y lo uso en App.js de la siguiente manera:

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>
        );
    }
};
...

Pero obtengo:

Screenshot 2020-02-27 at 22 27 01

Estoy usando:

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

¿Qué ocurre?

Está llamando a su componente Settings como una función y no como un componente de función.

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

Los ganchos no están permitidos dentro de las funciones simples, solo en los componentes de la función y la forma en que lo llamas trucos. Reacciona pensando que tu componente es en realidad una función normal.

Tal vez esto le ahorre a alguien el dolor de cabeza, si está usando react-router-dom si pasa su componente en un renderizado como este (no de la manera correcta) le dará Invalid Hook Call Warning
<Route path="/:cuid/:title" render={PostArticle} />

Me tomó media hora saber dónde me equivoqué

Esto puede ayudar a alguien: si experimenta este error después de usar react-router-dom, verifique cómo ha definido sus rutas. por ejemplo, debería ser <Route path={'/upgrade/:plan'} exact children={<Upgrade />} /> mientras estaba haciendo <Route path={'/upgrade/:plan'} exact children={Upgrade} />

Esto es especialmente incómodo si usa tinta o pastel para crear una CLI (consulte https://github.com/vadimdemedes/pastel/issues/2). No puedo convertirlo en un peerDep porque no puedo pedirles a todos los usuarios que instalen React y tampoco puedo obligarlos a usar una cierta versión/rango de React.

Mi equipo usa Yarn y recibía el error Invalid hook call solo en las pruebas, no en la aplicación. El problema era que react-test-renderer se estaba resolviendo en una versión inferior a la de react y react-dom , por lo que agregamos resolutions en package.json :

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

Para las personas que usan Gatsby en un subdirectorio, esta es una posible solución.

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'),
    },
  },
})

Tengo el mismo problema al ejecutar el comando npm link , hay un problema

Luego utilicé la solución oficial provista por reaccionar para resolver este problema.

Este problema también puede surgir cuando usa el enlace npm o un equivalente. En ese caso, su paquete podría "ver" dos React: uno en la carpeta de la aplicación y otro en la carpeta de su biblioteca. Suponiendo que myapp y mylib sean carpetas hermanas, una solución posible es ejecutar npm link ../myapp/node_modules/react desde mylib. Esto debería hacer que la biblioteca use la copia React de la aplicación.

Si A necesita presentar a B (A y B son hermanos)

  • paso 1 (en B)

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

    • npm link

  • paso 2 (en A)
    npm link B

esto funciona para mi

Incluso con estas respuestas, no estoy seguro de por qué recibo el error. Tengo mi biblioteca de dependencias vinculada a mi aplicación principal y después de recibir el error, seguí los documentos de reacción y vinculé la versión de reacción de mi biblioteca de dependencias a la reacción de mi aplicación (ejecutando npm link <>/webapp/node_modules/react . (Incluso hice esto con react- dom). Cuando inicié sesión para probar si React1 y React2 eran iguales, registró true por lo que no estaba usando versiones duplicadas de React, estaba usando las mismas versiones de React y estaba usando componentes de función Entonces, aunque el registro de prueba indicó que no tenía una versión duplicada de React, todavía recibía el error de enlace.

Pero probar esta solución como se mencionó anteriormente solucionó ese error en particular:

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

Así que estoy perdido.

Así que estoy perdido.

@orpheus ¿Representas más de una sola raíz de reacción en la misma página? es decir, ¿tiene más de una llamada ReactDOM.render en la misma página?

¿Representa más de una sola raíz de reacción en la misma página? es decir, ¿tiene más de una llamada ReactDOM.render en la misma página?

@timkindberg

No. Tengo mi ReactDOM.render en la raíz de mi app , y el módulo lib que estoy vinculando es una biblioteca de componentes y no usa un ReactDOM.render en absoluto.

editar: estoy haciendo algo similar a:

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

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

donde <Root /> representa algo como

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

PermissionsProvider es el componente React que importo desde mi módulo lib vinculado que usa un enlace que hace que la aplicación falle. Crea estado y contexto y representa a sus hijos.

Hola, estoy usando electrones con ganchos de reacción. si escribo mi propio gancho, funciona. Pero arroja un error cuando uso ganchos de otro paquete en node_module, como react-use , swr .

Tengo que copiar el paquete a mi archivo local.

¿Alguien se encuentra con este problema?

Ejemplo de proyecto aquí:
https://github.com/Zaynex/electron-react-ts-kit/tree/hooks-error

código central:
https://github.com/Zaynex/electron-react-ts-kit/blob/hooks-error/src/renderer/app.tsx

También sigo teniendo este problema incluso después de eliminar las copias duplicadas de react y react-dom. Creé un proyecto de prueba súper simple para reproducir.

$ 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

Actualmente, estoy usando el método de alias del paquete web, pero también probé el método npm link y ninguno funcionó.

Me encontré con este problema también. Estoy usando ExpressJS + Pug para renderizar vistas, luego escribí un renderizador (similar a ReactRails) que le permite renderizar componentes del lado del servidor y del cliente.

Traté de extraer esto a un paquete separado ya que se estaba complicando y me encontré con este problema.

Para solucionarlo, tuve que agregar debajo de la tecla resolve :

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

Ahora funciona como se esperaba cuando se ejecuta el paquete web normalmente, pero el problema persiste con un volumen acoplable. Soy demasiado nuevo en Docker para lidiar con eso, así que lo revisaré más tarde.

Editar: hablé demasiado pronto. Funciona bien ahora con React render, pero no con hidrato.

Hola, estoy usando electrones con ganchos de reacción. si escribo mi propio gancho, funciona. Pero arroja un error cuando uso ganchos de otro paquete en node_module, como react-use , swr .

Tengo que copiar el paquete a mi archivo local.

¿Alguien se encuentra con este problema?

Ejemplo de proyecto aquí:
https://github.com/Zaynex/electron-react-ts-kit/tree/hooks-error

código central:
https://github.com/Zaynex/electron-react-ts-kit/blob/hooks-error/src/renderer/app.tsx

Hola. Tuve el mismo problema. Estoy usando electron-webpack que marca todos los módulos como externos para webpack. Con pocas excepciones codificadas, como reaccionar y reaccionar-dom.
Para mí, eso significaba que la reacción cargada desde mi código era diferente a la reacción cargada desde dicho módulo.
Agregar estos módulos a la lista blanca parece ayudar (no estoy seguro si no rompió nada más todavía :)

@huhle gracias, ¡funciona! Tal vez deberíamos sumergirnos en electron-webpack.

Me las arreglé para hacer que esto funcione yo mismo. Creo que es una de las mejores soluciones cuando se trata de espacios de trabajo de Lerna y Yarn, y tal vez algunas de las piezas podrían usarse para otra solución.

Todo parece reducirse a la configuración del package.json que estoy importando. Necesitaba incluir estas secciones:

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

Después de hacer esto, tuve que reconstruir los proyectos y estaba listo y funcionando. Parece que enumerarlos como dependencias de pares permite que su proyecto de consumo requiera que los instalen. Y debido a que no están enumerados en las dependencias, no deberían estar disponibles para el paquete que está tratando de importar, pero por alguna razón, a menos que le diga que no se levante, permanecen disponibles y una nueva instancia de reacción entra y provoca el error.

¡Buena suerte!

Estoy tratando de usar react-spring para obtener un efecto de aparición gradual simple. Nada parece estar funcionando.
`importar React, { useState, useEffect } from 'react';
importar {animado, useTransition} de 'react-spring';

const TextContent = (accesorios) => {

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>
)

}

exportar contenido de texto predeterminado;
Capture

Intenté comprobar si tengo varias instancias de React. Npm ls-ing me dice que solo tengo una versión única de react y react-dom, ambas en 16.13.1.

Hola, estoy usando electrones con ganchos de reacción. si escribo mi propio gancho, funciona. Pero arroja un error cuando uso ganchos de otro paquete en node_module, como react-use , swr .
Tengo que copiar el paquete a mi archivo local.
¿Alguien se encuentra con este problema?
Ejemplo de proyecto aquí:
https://github.com/Zaynex/electron-react-ts-kit/tree/hooks-error
código central:
https://github.com/Zaynex/electron-react-ts-kit/blob/hooks-error/src/renderer/app.tsx

Hola. Tuve el mismo problema. Estoy usando electron-webpack que marca todos los módulos como externos para webpack. Con pocas excepciones codificadas, como reaccionar y reaccionar-dom.
Para mí, eso significaba que la reacción cargada desde mi código era diferente a la reacción cargada desde dicho módulo.
Agregar estos módulos a la lista blanca parece ayudar (no estoy seguro si no rompió nada más todavía :)

¡Brillante! Gracias

Estoy tratando de usar react-spring para obtener un efecto de aparición gradual simple. Nada parece estar funcionando.
`importar React, { useState, useEffect } from 'react';
importar {animado, useTransition} de 'react-spring';

const TextContent = (accesorios) => {

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>
)

}

exportar contenido de texto predeterminado;
Capture

Intenté comprobar si tengo varias instancias de React. Npm ls-ing me dice que solo tengo una versión única de react y react-dom, ambas en 16.13.1.

Aquí igual. react y react-dom están en 16.13.1 para mí, e intentar usar react-spring trae este mismo error.

De otro hilo en styled-components , aprendí que si está usando un paquete local propio a través de un URI file: en package.json , necesita rm -rf node_modules/local-package-name/node_modules antes de ejecutar su aplicación, porque aparentemente, los paquetes locales se copian sin verificar si hay dependencias redundantes en node_modules .

De otro hilo en styled-components , aprendí que si está usando un paquete local propio a través de un URI file: en package.json , necesita rm -rf node_modules/local-package-name/node_modules antes de ejecutar su aplicación, porque aparentemente, los paquetes locales se copian sin verificar si hay dependencias redundantes en node_modules .

Sí, este es el mismo problema para aproximadamente una docena de casos de uso solo en este hilo. Agregué un objetivo "prestart" y "prebuild" para hacer rm -rf (usando rimraf). Otro usuario en este hilo usó npm-link-shared en su preinicio para que los módulos compartieran la misma instancia de react. Muchos de nosotros, los usuarios de monorepo, nos encontramos con esto.

Hola, estoy usando electrones con ganchos de reacción. si escribo mi propio gancho, funciona. Pero arroja un error cuando uso ganchos de otro paquete en node_module, como react-use , swr .
Tengo que copiar el paquete a mi archivo local.
¿Alguien se encuentra con este problema?
Ejemplo de proyecto aquí:
https://github.com/Zaynex/electron-react-ts-kit/tree/hooks-error
código central:
https://github.com/Zaynex/electron-react-ts-kit/blob/hooks-error/src/renderer/app.tsx

Hola. Tuve el mismo problema. Estoy usando electron-webpack que marca todos los módulos como externos para webpack. Con pocas excepciones codificadas, como reaccionar y reaccionar-dom.
Para mí, eso significaba que la reacción cargada desde mi código era diferente a la reacción cargada desde dicho módulo.
Agregar estos módulos a la lista blanca parece ayudar (no estoy seguro si no rompió nada más todavía :)

Esto también se aplica a las personas que tienen problemas con redux o redux toolkit y electron-webpack. Tengo la siguiente configuración de trabajo:

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

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

Mi problema fue que escribí

import React from 'React'

En lugar de:

import React from 'react'

A veces son las cosas tontas.

Lo resolví agregando lo siguiente a la configuración de mi paquete web:

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

Inicialmente pensé que era un problema con el enlace npm, hice todo lo que se sugirió e incluso cambié a yarn. Eventualmente, pensé que algo más estaba sucediendo cuando publicar en npm dio el mismo error al importar en otro proyecto.

¿Alguien aquí ha solucionado esto recientemente con un lerna monorepo? He intentado algunas de las sugerencias sin suerte.

Me encuentro con el error después de agregar el código que se comenta con // a continuación. Agregar CssBaseline y la información del fragmento de reacción provoca el error. Todo funciona bien cuando está comentado. El código original es simplemente el código básico de npx create-react-app. Completamente nuevo en esto y algunas de las correcciones que probé desde arriba no tuvieron efecto.

importar React desde 'react';
importar logotipo desde './logo.svg';
importar CssBaseline desde '@material-ui/core/CssBaseline';

exportar función predeterminada App() {
regreso (

        //<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>

);
}

Para pruebas locales:
En la biblioteca node_modules, elimine la carpeta react y react-dom
En el paquete principal, ejecute "yarn install" o "npm install" nuevamente.

Esto evita que la segunda copia de react se cargue en el paquete principal. Obviamente, no es una solución permanente, pero funciona para las pruebas locales.

Para cualquiera que use lerna, puede encontrar este problema al ejecutar pruebas en un paquete, donde el código hace referencia a componentes en otro paquete.

El problema que experimentamos en este caso se debió a que la reacción se importó en la especificación y también se importó en un componente en el árbol de componentes que usaba withStyles de Material UI , que se implementa usando ganchos en Material UI.

Parece que reaccionar administra internamente el estado en una variable ReactCurrentDispatcher.current , y esto termina estableciéndose en una instancia de reaccionar, pero se usa en la otra instancia de reaccionar; cuando está vacío, arroja el Invalid hook call ... mensaje.

Ya estábamos usando Craco para anular la configuración del paquete web de Create React App en el momento de la compilación:

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

Sin embargo, esta anulación del paquete web solo se usa en el momento de la compilación; cuando se ejecutan las pruebas, el código no se compila, sino que se instancia desde la fuente, por lo que nuestra solución fue usar CracoAlias ​​en nuestro craco.config.js para especificar la ruta de reacción durante las pruebas:

  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',
        },
      },
    },
  ],

Usé @craco/craco como solución, sin expulsar, siguiendo el ejemplo de @apieceofbart . Los pasos para mí fueron los siguientes usando npm link para probar el módulo local:

  1. Instale craco en mi aplicación de demostración ejecutando npm i @craco/craco --save
  2. Cree el archivo de configuración craco.config.js en la raíz donde vive el paquete.json en la aplicación de demostración.
  3. Cambie los scripts start , build y test reemplazando react-scripts con craco en mi aplicación de demostración.
// 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"
  },
...
}

editar: ni siquiera me di cuenta de que @jasondarwin tenía la misma idea.

Pasé lo mejor de un día tratando de solucionar este problema. Publicando mi solución aquí en caso de que ayude a alguien.

Estamos usando un monorepo y dos paquetes estaban importando diferentes instancias de reaccionar, pero se estaban resolviendo en el mismo lugar en los módulos del nodo raíz. Resulta que teníamos estas dos instancias porque una de las aplicaciones estaba usando su propio paquete web para crear un paquete. Esto se elevó correctamente al módulo del nodo raíz, pero obtendría su propia instancia cuando lo importara ese paquete. La solución fue incluir reaccionar y reaccionar DOM en los elementos externos de la configuración del paquete web para que el paquete web no creara una nueva instancia de reacción para el paquete.

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

¡Espero que esto ayude a alguien!

Para mí, estaba usando la versión 4.0.0 de react-hot-loader, actualizar a react-hot-loader 4.8 parece funcionar

Recibo el mensaje Invalid hook call SOLAMENTE cuando ejecuto mis pruebas en un Hook personalizado que estoy creando para trabajar con ventanas modales.

Para demostrar el comportamiento, he creado un ejemplo a continuación:
(https://github.com/BradCandell/invalid-hook-example)

  • Solo una versión de react y react-dom

¿Me estoy perdiendo algo terriblemente obvio? Cuando rompí la regla en el pasado, el npm start fallaba. Pero esto solo está fallando en mis pruebas.

¡Agradezco la ayuda!
-Puntilla

Lo resolví agregando lo siguiente a la configuración de mi paquete web:

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

Inicialmente pensé que era un problema con el enlace npm, hice todo lo que se sugirió e incluso cambié a yarn. Eventualmente, pensé que algo más estaba sucediendo cuando publicar en npm dio el mismo error al importar en otro proyecto.

Esto me lo arregló. Estaba importando react-toastify y estaba recibiendo la llamada de enlace no válida. Revisé cada elemento en el error de la consola:

  1. Es posible que tenga versiones que no coincidan de React y React DOM.

    1. Podrías estar rompiendo las Reglas de los Hooks.

    2. Es posible que tenga más de una copia de React en la misma aplicación.

Terminó siendo el 3er número. Seguí esto:
https://reactjs.org/warnings/invalid-hook-call-warning.html#duplicate -react

Ninguna de las soluciones anteriores funcionó para mí, hasta que me di cuenta de que estaba empaquetando otra copia de reaccionar con la biblioteca que estaba _importando_.
Había transpilado y empaquetado el código fuente de mi biblioteca, por lo que la verificación de las diferentes versiones de React enumeradas en los documentos devolvía true en lugar de false .
Marcar react como una dependencia externa y dejarlo fuera del paquete de mi biblioteca funcionó.

Mi caso no era un monorepo, sino una situación algo parecida. Estamos desarrollando un nuevo marco de interfaz de usuario y, en lugar de usar npm link o lerna, solo usamos alias de paquete web para requerir los archivos en una carpeta hermana. Funciona bien, pero te encontrarás con este problema. Afortunadamente, la solución de @apieceofbart nos solucionó el problema.

Línea 130:21: React Hook "useStyles" se llama en la función "pharmacyDashboard" que no es un componente de la función React ni una función React Hook personalizada react-hooks/rules-of-hooks
Línea 133:45: React Hook "React.useState" se llama en la función "pharmacyDashboard" que no es ni un componente de la función React ni una función React Hook personalizada react-hooks/rules-of-hooks

este es el error... ¿alguien puede ayudarme a resolver esto?

@vyshnaviryali es mejor que llames a tu función usePharmacyDashboard

./src/components/HomeFiles/AppFooter.js
Línea 1:1: no se encontró la definición de la regla 'material-ui/no-hardcoded-labels' material-ui/no-hardcoded-labels'
por favor alguien me puede ayudar a resolver esto

Para todos los que tienen este problema con npm link porque necesitan agregar funciones a sus componentes pero no quieren npm publish antes de probar, me sorprende que nadie haya sugerido usar yalc (https://www.npmjs.com/package/yalc)

Para todos los que tienen este problema con npm link porque necesitan agregar funciones a sus componentes pero no quieren npm publish antes de probar, me sorprende que nadie haya sugerido usar yalc (https://www.npmjs.com/package/yalc)

De hecho, lo hice el año pasado: https://github.com/facebook/react/issues/13991#issuecomment -535150839

Llevamos casi un año usándolo sin ningún problema.

Otro aquí usando lerna; para arreglar esto, moví las dependencias react y react-dom a mi raíz package.json .

Tuve el mismo problema y lo resolví agregando:

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

a la propiedad resolve en la configuración del paquete web de mi aplicación principal.

Obviamente, fue mi error usar dos copias de React, pero estoy de acuerdo en que sería genial si el mensaje de error fuera mejor. Creo que esto es tal vez similar a: # 2402

Para aquellos que usan el método anterior pero aún reciben los errores cuando ejecutan jest, agréguelos a moduleNameMapper en la configuración de jest (omita react-dom si no es necesario):

moduleNameMapper: {

...

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

...

}

Estoy perdido. Recibo esto, pero mi aplicación no usa ningún gancho y no hay duplicados de reacción o reacción. Estoy usando next.js. ¿Puede eso tener algo que ver?

npm ls react
npm ls react-dom

@maapteh ¿ fue eso para mí? Ejecuté esos comandos y no encontré ningún duplicado. Ambas bibliotecas están en la versión 16.13.1

@dancancro También estoy usando Next.js y no puedo arreglar esto.

npm ls react y npm ls react-dom solo devuelven una entrada. Pero no estoy seguro de que eso sea correcto. Me encuentro con este error cuando me vinculo a un paquete local para el desarrollo. npm ls devuelve solo una entrada, incluso cuando no vinculo la reacción en la dependencia al repositorio principal. Pero incluso cuando hago que el enlace reaccione correctamente, sigo recibiendo el error.

@justincy No tengo ningún enlace de paquete en mi proyecto. Apuesto a que está relacionado con Next.js. El problema desaparece si pongo el componente principal dentro de un typeof document !== 'undefined' , lo que socava el propósito de Next.js

Logré solucionar mi problema eliminando react y react-dom de node_modules en la dependencia. No es lo ideal, pero al menos puedo seguir trabajando.

@dancancro Soy escéptico de que su problema sea causado por Next.js. Si lo fuera, muchas otras personas tendrían el problema. Solo me encuentro con él debido a los paquetes vinculados. No veo el error sin paquetes vinculados.

El problema desaparece si elimino cinco de los siete componentes del componente principal. No puedo ver nada especial acerca de estos componentes. Envolver estos componentes en typeof document !== 'undefined' s también funciona.

Hola equipo, estoy tratando de actualizar la versión de React de 16.2.0 a 16.13.1, también hice lo mismo para react-dom.
Ahora tengo un componente contenedor que se llama en "/ prueba"

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

en el envoltorio de prueba he importado un componente funcional con un gancho
function TestComponent(props) { useEffect(() => { console.log("TEST COMPONENT"); }); return ( <div> Hello world! </div> ) }

Pero cuando la página representa el gancho UseEffect no funciona y se produce un error, es decir, advertencia de llamada de gancho no válida
PD. :

  1. He comprobado que solo tengo una copia de react y react-dom está instalada
  2. La versión de React y React-dom es 16.13.1

eso es lo que tengo
Yo solo ...
@ @
ReactError
Uso nextJS para que no necesite importar React. Y lo intenté, no ayuda.

Todas las demás páginas y funciones funcionan perfectamente.

@Brotipok , ¿qué versión de next.js? (Al ver problemas similares, pero solo al pasar a 9.5 desde 9.4.X)

¡Hola!

Tengo el mismo error, solo un paquete para reaccionar y reaccionar dom cuando hago npm ls.

Versión de reacción: 16.13.1
Versión de Reactdom: 16.13.1

Estoy usando mecanografiado y he inicializado el proyecto con create-react-app my-app --template mecanografiado.

El componente funcional solo funciona si no estoy usando ganchos dentro de él.

Paquete.json

{
"nombre": "blablamovie",
"versión": "0.1.0",
"privado": cierto,
"dependencias": {
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.5.0",
"@testing-library/user-event": "^7.2.1",
"@tipos/broma": "^24.9.1",
"@tipos/nodo": "^12.12.53",
"@tipos/reaccionar": "^16.9.43",
"@types/react-dom": "^16.9.8",
"@types/react-router-dom": "^5.1.5",
"reaccionar-iconos": "^3.10.0",
"guiones de reacción": "3.4.1",
"mecanografiado": "^3.7.5",
"webpack-paquete-analyzer": "^3.8.0"
},
"guiones": {
"inicio": "inicio de scripts de reacción",
"construir": "construir scripts de reacción",
"prueba": "prueba de scripts de reacción",
"expulsar": "reaccionar scripts expulsar",
"analyze": "source-map-explorer 'build/static/js/*.js'"
},
"eslintConfig": {
"extiende": "aplicación de reacción"
},
"lista de navegadores": {
"producción": [
">0.2%",
"no muerto",
"no op_mini todo"
],
"desarrollo": [
"última versión de Chrome 1",
"última 1 versión de firefox",
"última 1 versión de safari"
]
}
}
Es un proyecto importante y me está volviendo un poco loco.
Si alguien puede ayudar sería genial.
Gracias.

@Brotipok , ¿qué versión de next.js? (Al ver problemas similares, pero solo al pasar a 9.5 desde 9.4.X)

Aquí están las dependencias
"dependencias": {
"siguiente": "9.4.4",
"imagenes-siguientes": "^1.4.0",
"nodo-sass": "^4.14.1",
"reaccionar": "16.13.1",
"react-document-meta": "^3.0.0-beta.2",
"reaccionar-dom": "16.13.1",
"reaccionar-línea-de-tiempo-horizontal": "^1.5.3",
"reaccionar-meta-etiquetas": "^0.7.4",
"reaccionar al hacer clic en el exterior": "^6.9.0"
},
"Dependencias de desarrollo": {
"@tipos/nodo": "^14.0.23",
"@tipos/reaccionar": "^16.9.43",
"mecanografiado": "^3.9.7"
}

Me encuentro con este mismo problema al importar componentes material-ui/core/Dialog , configuré mi package.json para usar reaccionar 16.8.0 específicamente para react y react-dom importaciones.

Ejecuté npm ls react y npm ls react-dom con solo una importación. También probé la prueba descrita en la página de error:

// 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);

Lo que devuelve false , sin embargo, ¿cómo rastrearía la versión de reacción "diferente" que está importando una dependencia? Parece que solo sucede cuando importo el componente Material UI Dialog , sucede tan pronto como toque un botón que lo activa para renderizar. Puedo usar otros componentes como List y ListItems , etc.

Intenté forzar resoluciones y tampoco lo solucionó.

No estoy usando un paquete web (un proyecto realmente pequeño), por lo que la compilación se realiza con react-scripts build si eso marca la diferencia.

Reescribir: simplemente reemplazaré mi pregunta con una referencia de solución (y tal vez una solicitud de mayor claridad de términos en los documentos, ¿para nosotros, tontos? :))

Antecedentes:
Estaba tratando de compilar en un paquete web un componente funcional con ganchos en un activo donde ese componente podría llamarse desde Vanilla JS en el navegador.

Por ejemplo,

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

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

... que quería exportar como un módulo en sí mismo, y después de cargar ese activo, usarlo directamente desde HTML, similar a:

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

Hice que esto funcionara hace mucho tiempo, siempre que el componente no contuviera ganchos. Pero cuando usaba ganchos, seguía encontrándome con este temido mensaje de error.

La solución increíblemente simple
Seguí _muchas_ pistas falsas más complicadas (múltiples versiones/instancias de react/reactDOM, importaciones de npm y dependencias secundarias ocultas, react-hot-loader, configuración de paquete web, elementos externos, diferentes convenciones de paquete/módulo/biblioteca, estructura posterior a la compilación... .) antes de probar esto, que funcionó:

export default () => <Example />;

(o export default props => <Example {...props} /> cuando corresponda).

En retrospectiva 20/20 tiene sentido, supongo.

Pero solo para señalar la fuente de confusión en caso de que alguien más lo necesite: los documentos de reglas de ganchos dicen _Llámelos en el nivel superior en el cuerpo de un componente de función_. Lo cual pensé que hice, ya que en realidad pegué el ejemplo directamente en mi estructura.

Mi interpretación es que esto , a partir de los ejemplos...

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>
  );
}

... NO es un componente de función en sí mismo? Se vuelve así en el contexto de llamada correcto (entonces, no Example() sino <Example /> ).

Supongo que me lo habré perdido en algún otro lugar de los documentos, pero en caso de que no: me habría ahorrado mucho tiempo si se incluyera/mencionara/vinculara un poco de contexto de uso (o simplemente una configuración de módulo ES). :) Sobre todo porque la versión directa export default Example funciona sin ganchos.

¡Gracias por una solución funcional @apieceofbart! Mi problema estaba relacionado con el enlace npm.

Así es como lo hice funcionar con la aplicación Create React, donde la configuración del paquete web está oculta por diseño. ¿También podría ser tu solución @florianzemma?

  1. npm install -D react-app-rewired
  2. Cree un archivo llamado config-overrides.js en su raíz del proyecto.
// 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. Reemplace los comandos react-scripts ... relevantes en package.json con react-app-rewired ... .

Espero que ayude

Recibí este error porque cargué los paquetes 2 veces.
En mi caso, sucedió porque la plantilla nunjucks donde se representaron las etiquetas de script se usó 2 veces: en el diseño en sí y, en general, en la plantilla para el contenido de la etiqueta principal,

solución de hilo

Estoy usando Yarn y solucioné esto forzando la resolución en mi package.json :

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

Además de agregar la resolución en la aplicación principal (biblioteca de consumo), actualicé las dependencias de la biblioteca con los siguientes comandos:

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

Después de esto, volví a vincular la biblioteca en la aplicación principal con yarn add link:/path/to/library

Hola
Me encuentro con el mismo problema con los espacios de trabajo de hilo.
Tengo un diseño como este:

espacio de trabajo/
├── biblioteca/
├── aplicación1/
├── aplicación2/

app1 y app2 tienen dependencias directas para reaccionar v16.9.0, reaccionar-dom v16.9.0 y 'biblioteca'.
'library' tiene una dependencia de pares para reaccionar v16.9.0 pero también una dependencia de desarrollo en storybook.
El problema parece provenir del libro de cuentos que depende de reaccionar v16.13.1.
Sin embargo, cuando ejecuto yarn install, termino con react 16.13.1 en mis node_modules de nivel superior y react 16.9.0 en los node_modules locales de app1 y app2.

Cuando ejecuto la aplicación 1 (creada con CRA), está usando su React v16.9.0 local, pero los componentes de la 'biblioteca' están usando React v16.13.1

Me parece que esto es un problema con la lógica de elevación de hilo, la definición del paquete web de crear-reaccionar-aplicaciones o ambos.
¿Alguien tiene alguna idea de una solución para este escenario?

Hola
Me encuentro con el mismo problema con los espacios de trabajo de hilo.
Tengo un diseño como este:

espacio de trabajo/
├── biblioteca/
├── aplicación1/
├── aplicación2/

app1 y app2 tienen dependencias directas para reaccionar v16.9.0, reaccionar-dom v16.9.0 y 'biblioteca'.
'library' tiene una dependencia de pares para reaccionar v16.9.0 pero también una dependencia de desarrollo en storybook.
El problema parece provenir del libro de cuentos que depende de reaccionar v16.13.1.
Sin embargo, cuando ejecuto yarn install, termino con react 16.13.1 en mis node_modules de nivel superior y react 16.9.0 en los node_modules locales de app1 y app2.

Cuando ejecuto la aplicación 1 (creada con CRA), está usando su React v16.9.0 local, pero los componentes de la 'biblioteca' están usando React v16.13.1

Me parece que esto es un problema con la lógica de elevación de hilo, la definición del paquete web de crear-reaccionar-aplicaciones o ambos.
¿Alguien tiene alguna idea de una solución para este escenario?

La única solución que encontré para esto fue yarn run eject la aplicación CRA y cambiar el orden de la sección resolve de:

```javascript
módulos: ['node_modules', paths.appNodeModules].concat(
módulos.additionalModulePaths || []
),
````

para
```javascript
módulos: [paths.appNodeModules, 'node_modules'].concat(
módulos.additionalModulePaths || []
),
````

Me parece extraño que 'appNodeModules' no sea la prioridad más alta. ¿Seguramente la aplicación real en cuestión debería ser diferida cuando se trata de resolver dependencias?

Encontré el problema de los 'ganchos' en un entorno que involucraba Webpack y Electron. Mi proyecto tiene una dependencia de un módulo A que a su vez está incluido en Webpack (y que yo mismo creé). Externalicé React de A (declarándolo como un módulo commonjs2). Esto excluye los archivos React del paquete de la biblioteca.

Mi programa principal, que se ejecuta en el proceso Electron Renderer, también usa React. Hice que Webpack incluyera React en el paquete (sin configuración especial).

Sin embargo, esto produjo el problema de los 'ganchos' debido a dos instancias de React en el entorno de tiempo de ejecución.

Esto es causado por estos hechos:

  • el módulo A 'requiere' React y esto se resuelve mediante el sistema de módulos de Electron. Entonces Electron toma React de node_modules;
  • el programa principal se basa en el tiempo de ejecución de Webpack para 'cargar' React desde el propio paquete.
  • tanto Electron como el tiempo de ejecución de Webpack tienen su propio módulo de caché...

Mi solución fue externalizar React también desde el programa principal. De esta manera, tanto el programa principal como el módulo A obtienen su React de Electron, una única instancia en la memoria.

Probé una cantidad de alias, pero eso no resuelve el problema, ya que un alias solo indica a Webpack dónde encontrar el código del módulo. ¡No hace nada con respecto al problema de múltiples cachés de módulos!

Si se encuentra con este problema con un módulo que no puede controlar, averigüe si React se externaliza y cómo. Si no se externaliza, creo que no puede resolver este problema en el contexto de Electron. Si solo se externaliza como global, coloque React en su archivo .html y haga que su programa principal también dependa de eso.

Finalmente...

//webpack.config.js

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

Vue3 tiene el mismo problema

Resolví este problema poniendo react y react-dom como peerDependencies en mi paquete.json de mi biblioteca externa, que usa React.

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

Supongo que me lo habré perdido en algún otro lugar de los documentos, pero en caso de que no: me habría ahorrado mucho tiempo si se incluyera/mencionara/vinculara un poco de contexto de uso (o simplemente una configuración de módulo ES). :) Sobre todo porque la versión directa export default Example funciona sin ganchos.

Hola @espen42 ,
Realmente esperaba que su solución nos ayudara. Literalmente probamos _todo_, tal como lo mencionaste.

Desafortunadamente, su solución tampoco parece ayudar. Me pregunto tal vez me perdí algo.

Entonces, en un paquete (lo llamaré @bla/bla), tenemos el index.js que tiene un componente con ganchos, como

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

Compilamos el paquete usando npx babel .

Vinculamos este paquete con npm link y luego lo incluimos en el proyecto como npm link @bla/bla .
Tanto el paquete como el proyecto usan la misma versión de React y react-dom.

En el proyecto, incluimos el paquete así:

import Bla from `@bla/bla`

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

export default RenderBla

Desafortunadamente, el error aún persiste.
Invalid hook call. Hooks can only be called inside of the body of a function component.

¿Qué nos puede estar faltando?

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

Este solucionó el problema para mí, muchas gracias hombre ❤️

Error del personalizador de campo cuando se accede a través de un vínculo externo (Sharepoint Online)

Una extensión del personalizador de campo spfx con algunos componentes de interfaz de usuario de fabric, cuando se accede a través de un enlace, obtiene uno de estos errores según la versión de fabricUI:
https://reactjs.org/docs/error-decoder.html/?invariant=321 ,
https://reactjs.org/docs/error-decoder.html/?invariant=290&args []=A.%20General

cuando se actualiza la página, todo funciona correctamente.
No he usado ningún React Hooks en el código, solo React Components.
Tampoco he usado referencias.

Creo que podría deberse a Fabric ui porque cuando se eliminan todos los componentes de fabric ui, no se produce ningún error.

Probé diferentes versiones de fabic ui, 6.189.2, 6.214.0 y 7.114.1 y también intenté reemplazar todas las referencias de fabric-ui con fluid ui, aún persiste el problema

verificó las versiones de reacción, aquí está la salida
npm ls reaccionar
+-- @microsoft/sp- webpart [email protected]
| +-- @microsoft/ [email protected]
| | -- [email protected] deduped | +-- @microsoft/[email protected] | | -- [email protected] deduplicado
| +-- @microsoft/sp-property-pane@ 1.9.1
| | -- [email protected] deduped | -- [email protected] deduplicado
`-- [email protected]

Hola a todos,
También me topé con este molesto error. En mi caso, esto también fue una configuración incorrecta de la compilación de mi paquete web al final. Pero ninguna de las cosas sugeridas en este número me ha funcionado. Así que quiero compartir mi experiencia también.

Mi página incluye varios puntos de entrada y SplitChunkPlugin puede crear fragmentos de tiempo de ejecución. Debido a que estamos usando la gema rails-webpacker, se configuró de forma predeterminada para crear un tiempo de ejecución para cada fragmento. Pero webpack hace algo similar por defecto, incluye el tiempo de ejecución dentro de los fragmentos.

Por supuesto, la documentación advierte sobre este caso, pero hay que encontrarlo. Establecer optimization.runtimeChunk en single creará un tiempo de ejecución separado. Esto evitará que su compilación cree instancias de múltiples copias de reaccionar, cuando use reaccionar desde múltiples puntos de entrada.

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

Hola a todos,
Tengo el problema de que quiero usar una biblioteca externa que proviene de un CDN y está incluida con una etiqueta <script> , por lo que no hay mucho que pueda hacer con el código en sí. La lib usa react y hooks, así que obtengo el
3. You might have more than one copy of React in the same app error.
Lamentablemente, no hay un paquete NPM para la biblioteca: https://github.com/Anyline/anyline-ocr-anylinejs-module
Estoy usando CRA y el proyecto no se expulsa.

Creó un pequeño ejemplo de Sandbox .

Lanza el mismo error ya que el otro paquete también usa ganchos pero con su propio React. Tuve que publicar mi paquete en NPM y luego importarlo directamente desde NPM. Que

Entro en este tema recientemente y me pregunto por qué.
Lo resolví subiéndolo a GitLab e instálelo por dirección.
¿Cuál es la diferencia entre paquete y paquete local?

Descubrí que recibo el mensaje "Llamada de gancho no válida". cuando cargo dinámicamente el Componente que está llamando al gancho.

Zona de pruebas de código

La prueba que carga "App" pasa estáticamente. Las dos pruebas que lo cargan dinámicamente (una que usa require y otra que usa import como función) dan el error.

Por qué me importa: estoy tratando de escribir algunas pruebas en las que estoy usando jest.doMock para simular algunas cosas y luego cargando dinámicamente el módulo que quiero probar, según la documentación . Estoy usando doMock en lugar de Mock porque necesito poder simular cosas de manera diferente en diferentes funciones. Sin embargo, notará que el error ocurre sin ninguna burla involucrada.

Lanza el mismo error ya que el otro paquete también usa ganchos pero con su propio React. Tuve que publicar mi paquete en NPM y luego importarlo directamente desde NPM. Que

Entro en este tema recientemente y me pregunto por qué.
Lo resolví subiéndolo a GitLab e instálelo por dirección.
¿Cuál es la diferencia entre paquete y paquete local?

@catsheue fue React1 === React2 true para ti?
no he publicado el mío en npm pero quería saber si esa es la causa

el mío parece ser React1 === React2 = true y no he encontrado la solución de por qué sucede esto cuando estoy importando mi biblioteca de reacción a un proyecto

Tuve este mismo problema al usar yarn link para probar una biblioteca local. Mi error fue enumerar react y react-dom como dependencias de desarrollo no pares.

Así que debería haber hecho yarn add --peer react react-dom . Finalmente, debido a que ya cometí el error de confirmar React como una dependencia de desarrollo, necesitaba eliminar node_modules de mi biblioteca. rm -rf node_modules; yarn me solucionó el problema.

Yo también enfrenté este problema. En mi caso, fue causado por un React duplicado de Storybook (v6.0.28). Creo que puedes encontrar más información aquí .

Desinstalé las dependencias de Storybook, eliminé node_modules y ejecuté yarn install nuevamente. Esto funcionó para mí. Espero que ayude a alguien a evitar las lágrimas y las horas perdidas en esto.

Esta solución también funciona para mí. Estoy usando Firebase Functions y tengo una carpeta node_modules tanto en la raíz de mi proyecto como en el directorio /functions/ . Si elimino /functions/node_modules , mi aplicación funciona bien. Esta es una solución, pero es bastante molesta. ¿Alguien ha encontrado una solución alternativa que permita que ambas carpetas node_modules existan al mismo tiempo?

Para la posteridad y cualquiera que pueda estar enfrentando este problema al usar mdbootstrap en una aplicación creada con create-react-app .

Vi este error al agregar varios componentes de mdbootstrap, como botones e imágenes de tarjetas. La salida de la consola agregada a index.js para la resolución de problemas según el artículo de soporte de React devolvió true al comparar versiones. Así que tuve que probar algo más.

La solución fue ejecutar un npm dedupe

npm ls react

+-- [email protected]
| `-- [email protected]
`-- [email protected]

npm dedupe

npm ls react

+-- [email protected]
| `-- [email protected]  deduped
`-- [email protected]

Después de esto, todos los componentes funcionaron bien. Días felices.

Descubrí que recibo el mensaje "Llamada de gancho no válida". cuando cargo dinámicamente el Componente que está llamando al gancho.

Zona de pruebas de código

La prueba que carga "App" pasa estáticamente. Las dos pruebas que lo cargan dinámicamente (una que usa require y otra que usa import como función) dan el error.

Por qué me importa: estoy tratando de escribir algunas pruebas en las que estoy usando jest.doMock para simular algunas cosas y luego cargando dinámicamente el módulo que quiero probar, según la documentación . Estoy usando doMock en lugar de Mock porque necesito poder simular cosas de manera diferente en diferentes funciones. Sin embargo, notará que el error ocurre sin ninguna burla involucrada.

@ miket01 Exactamente lo que trato de hacer (pero sin burlarme). ¿Encontraste alguna solución?

Encontré esto haciendo:

function HeadedSection (props) {
   if (!ReactDOMServer.renderToStaticMarkup(props.children))
        return null;

    const [hidden, set_hidden] = useState(props.hidden);

Solucionado llamando primero a useState :

function HeadedSection (props) {
    const [hidden, set_hidden] = useState(props.hidden);

    if (!ReactDOMServer.renderToStaticMarkup(props.children))
        return null;

Todavía recibo este error después de dejarlo de lado durante muchos meses.

Uso cero ganchos en mi programa. Hay exactamente una copia de react y una copia de react-dom y son la misma versión. No hay enlaces.

Había funcionado en parte antes de que intentara actualizar algunos paquetes para solucionar problemas de seguridad. Estoy usando next.js y la solución fue excluir algunos subcomponentes del componente de nivel superior envolviéndolos en {typeof window !== 'undefined' pero ahora eso tampoco funciona.

[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

El error se genera porque ReactCurrentDispatcher.current === null pero no puedo encontrar ningún lugar en /node_modules/react/cjs/react.development.js donde esto esté configurado en algo.

¿Alguien puede decirme dónde ReactCurrentDispatcher.current debería obtener un valor?
https://github.com/facebook/react/search?p=2&q=%22ReactCurrentDispatcher.current+%3D%22&type=code

Parece un candidato, pero este código no está contenido en mi react-development.js . ¿Deberia ser?

    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

Recibo este error con la representación del lado del servidor por next.js y este código está en la fuente de reacción en react-dom/server . ¿Cómo puedo determinar si /node_modules/react/cjs/react-development.js es correcto?

ACTUALIZACIÓN: Este era el problema. Había editado webpack.config.externals en mi archivo next.config.js
https://github.com/vercel/next.js/issues/17592#issuecomment-712443172

Mi aplicación arroja un error masivo (llamada de enlace no válida) cada vez que intento integrar la interfaz de usuario del material en ella. Soy completamente nuevo en React, así que necesito ayuda.

¿Fue útil esta página
0 / 5 - 0 calificaciones