React: Hooks + várias instâncias de React

Criado em 27 out. 2018  ·  285Comentários  ·  Fonte: facebook/react

Para pessoas provenientes da pesquisa: leia esta página primeiro . Ele contém as correções mais comuns possíveis!

Deseja solicitar um recurso ou relatar um bug ?

Aprimoramento

Qual é o comportamento atual?

Eu tive várias instâncias do React por engano.

Ao tentar usar ganchos, recebi este erro:
hooks can only be called inside the body of a function component

O que não está correto, pois eu estava usando componentes de função. Demorei um pouco para encontrar a verdadeira causa do problema.

Qual é o comportamento esperado?

Mostre a mensagem de erro correta. Talvez detecte que o aplicativo possui várias instâncias do React e diga que pode ser o motivo dos bugs.

Hooks Discussion

Comentários muito úteis

Eu tive o mesmo problema e resolvi adicionando:

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

para a propriedade resolve na configuração do webpack do meu aplicativo principal.

Obviamente foi um erro meu usar duas cópias do React, mas concordo que seria ótimo se a mensagem de erro fosse melhor. Eu acho que isso talvez seja semelhante a: https://github.com/facebook/react/issues/2402

Todos 285 comentários

Então, apenas para esclarecimento: você estava importando um gancho (digamos useState ) de um módulo react diferente daquele usado para renderizar o componente?

Concordo que isso é confuso. Não tenho certeza se temos uma maneira de saber se algum outro módulo React está renderizando. AFAIK, tentamos executar o React isoladamente o máximo possível para que várias instâncias do React possam funcionar no mesmo contexto global sem problemas.

Caso contrário, provavelmente poderíamos atualizar a mensagem de erro e mencionar este caso também, se não for muito confuso.

Sim, eu comparei React1 === React2 e foi false (React1 sendo de index.js e React2 sendo do arquivo usando o gancho). Quando isso acontece, os ganchos falham com a mensagem de erro genérica acima.

Esta questão é para aumentar a conscientização sobre este caso e talvez melhorar a mensagem de erro de alguma forma para ajudar as pessoas que enfrentam isso. É provavelmente muito borda embora.

Sim, tentei vincular o npm a um pacote que estou criando. Ele lança o mesmo erro, pois o outro pacote também está usando ganchos, mas com seu próprio React. Eu tive que publicar meu pacote no NPM e depois importá-lo diretamente do NPM. Dessa forma, o erro desapareceu, mas espero que isso seja corrigido, pois publicar um pacote sem testá-lo é ruim, obviamente

Lerna monorepos sofre com isso também quando um gancho personalizado é definido em um pacote e usado por outro, pois as dependências com links simbólicos usam sua própria cópia do react.

Eu tenho uma solução (hacky) no momento usando npm-link-shared e um script npm prestart para substituir essencialmente a dependência react de um pacote por um link simbólico para o outro, então eles usam a mesma instância.

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

Eu tive o mesmo problema e resolvi adicionando:

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

para a propriedade resolve na configuração do webpack do meu aplicativo principal.

Obviamente foi um erro meu usar duas cópias do React, mas concordo que seria ótimo se a mensagem de erro fosse melhor. Eu acho que isso talvez seja semelhante a: https://github.com/facebook/react/issues/2402

@mpeyper Funciona. Obrigado

@apieceofbart Isso funcionou para mim. Obrigado pela sugestão. 👍

Pelo que entendi, esse problema surge quando há várias cópias do React no mesmo pacote.

Isso também é um problema se dois pacotes separados com suas próprias cópias do React estão inicializando seus próprios aplicativos React em elementos dom separados, como descrito aqui: https://medium.jonasbandi.net/hosting-multiple-react-applications-on- o-mesmo-documento-c887df1a1fcd

Eu acho que o último é um padrão de "integração" comum usado, por exemplo, no meta-framework de spa único (https://github.com/CanopyTax/single-spa).

Também estou tendo esse problema, mesmo com exatamente as mesmas versões de reação, o desenvolvimento de ganchos para serem publicados por conta própria é quebrado ao usar npm-link . Recebendo a mesma mensagem inútil hooks can only be called inside the body of a function component . A solução de alias do @apieceofbart resolveu isso para mim. Muito obrigado!

Mesmo problema aqui quando eu npm link um pacote para meu aplicativo principal. Não consegui fazer babel-plugin-module-resolver funcionar.
Diz:
Could not find module './node_module/react'
Isso é irritante porque me impede de testar meu componente localmente antes de publicá-lo.

Corrigi meu problema removendo o acento circunflexo em "react": "^16.7.0-alpha.2"
Aqui está o comentário completo: https://github.com/facebook/react/issues/14454#issuecomment -449585005

Estou usando o Yarn e consertei isso forçando a resolução no meu package.json :

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

Mesmo aqui!!

Só queria deixar uma nota aqui para quem pode ter tido esse problema da mesma maneira que eu.

Estamos rodando React e Rails com a gem react-rails e renderizando componentes diretamente nas views do Rails. Eu estava recebendo esse erro toda vez que uma nova versão do aplicativo era enviada, porque o Turbolinks estava pegando o novo pacote JS do <head> que carregava uma instância extra do React. A solução foi fazer com que o Turbolinks fizesse uma recarga de página inteira quando detectasse que o pacote foi alterado: https://github.com/turbolinks/turbolinks#reloading -when-assets-change

Isso parece ter resolvido para nós.

Estou muito animado para finalmente colocar Hooks em produção, e todos nós devemos um enorme obrigado a todos que tornaram isso possível. Eles são muito divertidos de se trabalhar e tornaram meu código mais curto e mais declarativo.

Apenas como um aviso, esse problema ainda é relevante na versão lançada com a mesma mensagem de erro inútil de "Os ganchos só podem ser chamados dentro do corpo de um componente de função".

Isso é algo que pode ser corrigido? Imagino que isso possa se tornar cada vez mais prevalente à medida que mais desenvolvedores começarem a implementar os novos recursos, e uma mensagem de erro mais clara percorreria um longo caminho em vez de uma "correção" definitiva.

Obrigado novamente por todo o trabalho duro e parabéns pelo lançamento! É realmente um conjunto incrível de recursos.

Edit : Deveria ter olhado mais de perto os PRs abertos, acabei de encontrar o nº 14690 que aborda isso. Obrigado @threepointone!

@taylorham O link no commit ainda não aponta para nada. Vou esperar por isso, mas este é um problema que tenho tido desde o uso de ganchos em um pacote vinculado _(a partir de npm link )_ e é impossível trabalhar com ele localmente sem publicar.
Depois de procurar vários problemas, pensei que isso era um problema com o react-hot-loader que estava compilando componentes para classes, mas mesmo depois que eles lançaram uma versão com suporte a Hook , ainda falha da mesma maneira.
Eu tentei um monte de hacks diferentes, mas sem sorte. Eu não sei por que todo mundo ainda não foi atingido com esse problema 🧐

@dotlouis Sim, é apenas uma mensagem de erro atualizada até agora e o problema em si ainda é uma dor.

A única coisa que funcionou para mim é fazer com que qualquer aplicativo que estou desenvolvendo dependa da instância do React da biblioteca usando "react": "link:../my-library/node_modules/react" .

  • nenhuma das resoluções propostas funcionou para mim, e eu tenho tentado todas
  • tentando instalar em um contexto de implementação de projeto e muitos HOCs
  • começar a partir de um projeto em branco fez o truque
  • eu continuo procurando a causa

[ok] para mim, a correção não era sobre package.json ou outros double react cause: eu tinha um themeProvider global em cima do meu aplicativo, vindo do contexto. Substituí-lo por um "useContext Hook" (enquanto o reescreve como uma composição funcional) parecia ser a única solução
Talvez haja um problema quando

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

Estou desenvolvendo um componente onde existe uma pasta example que usa create-react-app .

Fazer isso em package.json resolveu este problema para mim:

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

@taylorham @DylanVann Obrigado por sua contribuição pessoal. Infelizmente, ainda não funciona para mim.
E não consegui encontrar nenhuma documentação sobre esse protocolo link: que você usou.
Basicamente, ele diz que "react-spring" (outro dep que também usa react como uma dependência) não pode encontrar react-dom . Você pode me indicar alguma documentação sobre "react": "link:../some/path" por favor?

Também estou usando o pacote de interface do usuário vinculado e consegui corrigir esse problema.
Você precisa exportar reagir renderToString da interface do usuário (pacote vinculado).
Eu criei a função de renderização no pacote vinculado.

Apenas para um contexto melhor - https://github.com/facebook/react/issues/14257

Obrigado @theKashey. @gaearon parece pensar que é o comportamento normal. Eu entendo que o React não deve ser carregado duas vezes, mas qual é a maneira recomendada de trabalhar com um pacote local vinculado?

Também tive problemas com os espaços de trabalho do Lerna sendo vinculados corretamente. Este foi o truque que usei para fazer isso funcionar. Certifique-se de executar npm install depois.

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

Há muitas maneiras de resolvê-lo, e as resoluções de fios geralmente não ajudariam - está mais relacionado à "ferramenta de construção"

  • para webpack use aliases - apenas um alias "difícil" tudo se desvia como react para um único arquivo
  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 brincadeira use moduleNameMapper
"jest": {
    "moduleNameMapper": {
      "^react$": "<rootDir>/node_modules/$1",
    },

@theKashey obrigado por seus insights, isso faz sentido quando consideramos como a resolução do módulo é feita (em baixo, depois na árvore), mas do ponto de vista do usuário, não acho isso muito prático. Quando eu npm link um pacote, eu esperaria que ele funcionasse sem ter que reconectar as dependências explicitamente. Isso torna o desenvolvimento de um pacote localmente bastante doloroso.

Esta é uma pedra angular, é assim que node_modules foi projetado para funcionar, é por isso que você pode ter duas versões de um Button em duas versões principais diferentes, e os módulos dependentes encontrarão facilmente o "certo" versão de um pacote.
É assim que deve funcionar o tempo todo.

Node.js internos são bastante simples - tente abrir um arquivo adicionando todos os prefixos conhecidos (como node_modules ) ou extensões (como js , ts , json ); se nenhum for encontrado, suba um diretório. A única maneira de "corrigir" - substitua o sistema de resolução do módulo nodejs.

yarn pnp fará isso e poderá resolver o problema. yarn workspaces , que pode _elevar_ pacotes compartilhados para o topo - também resolverá o problema sem nenhuma "mágica" envolvida.

npm workspaces ? Não existe agora.

Na verdade, acabei mudando meu projeto para usar espaços de trabalho. Ele resolve isso sem ter que usar resoluções, e o içamento/estrutura é benéfico de qualquer maneira.

Este era um quebra cabeça. Eu tentei a configuração do webpack resolve.alias mas não estava funcionando, tentei muitas configurações também, mas nunca consegui fazê-lo funcionar infelizmente, mas aqui está como eu finalmente consegui fazê-lo funcionar:

Aqui está minha estrutura de pastas:

Projeto
|
+-- node_modules
|
+-- construir
| |
| +-- index.js
|
+-- exemplo (create-react-app)
| |
| +-- pacote.json

Eu tive que modificar meu package.json dentro da pasta de exemplo, essencialmente puxando o react dos node_modules 'principais' do projeto com base na sugestão de @jmlivingston , eis como acabou:

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

Agora depois disso eu corri npm install e então corri npm link , isso funcionou.

Espero que isso possa ajudar outra pessoa e economizar algum tempo.

Então, alguma correção para este problema? Eu tentei tantas recomendações aqui como eu posso e sem sorte. Estou usando create-react-app e typescript. Usando React/React-dom 16.8.3. Este é um novo projeto que criei há 2 dias tão bem simples. Estou usando useSpring() e animado.div. Obrigado

@guru-florida você está usando react-router por acaso?

Estou usando a mesma pilha que você (typescript e create-react-app) e meu problema com o atributo render . Mudar para component resolveu o problema.

Antes de:

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

Depois de:

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

Espero que ajude..!

@mikeyyyyyy Não, não usando React Router neste. Obrigado pela dica, porque eu estava no último projeto que tentei usar o spring e tive o mesmo problema.

Eu tive esse problema com o link npm (em um aplicativo de pacote), o npm link .../whatever/node_modules/react não parece resolvê-lo, mas funciona bem com componentes que não são de gancho

@tj Acho que você tem problemas com ssr. A solução rápida é exportar funções de reação ou reação inteira do pacote vinculado e importá-lo no pacote do servidor

@seeden ahh não estou usando SSR, apenas um SPA com Parcel. Eu tenho um pacote ui internamente para minhas próprias coisas e um aplicativo no qual estou trabalhando, ambos têm a mesma versão react , parece estranho que haja uma duplicata, mas talvez seja uma preocupação do pacote

@tj oh, entendo. Então boa sorte com este problema muito estranho. fiquei uma semana com isso

Então, alguma correção para este problema?

Não há problema aqui em si. Conforme explicado nesta página , React precisa que as chamadas useState() estejam no mesmo objeto react que o objeto react como "visto" de dentro de react-dom . Se não é isso que acontece com você, significa que você está agrupando duas cópias do React na página - o que é ruim por si só e também quebra alguns outros recursos antes dos Hooks. Então você vai querer corrigi-lo de qualquer maneira. Esta página contém maneiras comuns de diagnosticar para corrigi-lo.

Estamos deixando esta discussão aberta para compartilhar soluções específicas quando as pessoas se deparam com esse problema. Mas não é um problema em si que possa ser "consertado" por qualquer pessoa além de você.

Eu tive esse problema com o link npm (em um aplicativo de pacote), o link npm .../whatever/node_modules/react não parece resolvê-lo, mas funciona bem com componentes que não são de gancho

Você se importa de criar um pequeno caso de reprodução?

@gaearon vai fazer, deve ter tempo para cavar um pouco mais na próxima semana

Felizmente, require-control corrigiu nosso problema com o contexto estático de yarn link + SSR + styled-components 4. Obrigado @theKashey 👍

Tentei de tudo aqui e falhei. Na verdade, foi algo diferente não documentado aqui. Tinha a ver com a diferenciação de maiúsculas e minúsculas das importações de reação . Em alguns casos tivemos:

import React from 'react'

E em outros:

import React from 'React'

Em alguns sistemas de arquivos (unix, osx) isso faz com que o Webpack instancie duas cópias do React.

Isso causou uma confusão extrema, pois pude ver claramente que só temos uma cópia do React; mas, em vez disso, era a maneira como estávamos importando.

O teste na documentação do react também sai bem, pois obviamente usa apenas letras minúsculas.

Isso soa como se fosse digno de uma menção nos documentos?

Para mim, o motivo de várias instâncias do React foi o Webpack DllPlugin. Para minha DLL de fornecedor eu não incluí react e react-dom na minha lista de entradas, no entanto, eu tinha outras bibliotecas que exigiam react ou react-dom então minha DLL continha react e react-dom (verificação rápida do arquivo json manifesto pode revelar isso). Então, quando eu estava executando o código e importando o React para o aplicativo, ele estava carregando de node_modules , mas no código dos fornecedores, o React era necessário do arquivo DLL.

Geral : tenha cuidado com arquivos DLL e certifique-se de que seus módulos incluídos não incluam dependências extras que você não precisa, caso contrário, você os importará duas vezes.

Consegui corrigir isso atualizando react-hot-loader para 4.6.0

isso fez o truque para o material npm link em Parcel:

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

não tenho certeza se é isso que ele tentará usar para uma compilação de produção, parece meio hacky, mas funciona pelo menos para o desenvolvimento

@theKashey OMG cara, funciona! Eu tentei muitas soluções diferentes que as pessoas sugerem relacionadas a esses problemas: desmontando com package.json deps, rastreando "duas reações" no projeto, verificando se estou quebrando a *regra dos ganchos` (que estou não), mas acho que sua opção com:

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

nos permite mover nosso projeto para o próximo lvl, usando ganchos em nosso app-as-a-lib .

Este é o webpack.config.js resultante

npm ls react

retorna

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

para mim

console.log(window.React1 === window.React2) retorna verdadeiro
neste momento estou pensando que é SSR causando o problema

Atualizar. De fato, foi causado pelo comportamento SSR do React-apollo (https://github.com/apollographql/react-apollo/issues/2541)
Atualizando para 2.3.1 corrigiu

Olá pessoal, nossa equipe enfrenta esse problema e levou alguns dias para resolver.

as soluções de trabalho para nós

Solução A: especifique a posição do pacote a ser procurada, conforme mencionado acima

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

Solução B: use o webpack resolve.modules para priorizar a pasta node_modules correta para procurar módulos

histórico do caso e por que isso acontece

Primeiramente, não é culpa do react, nem mesmo do lerna, mas react, webpack e npm-link podem precisar assumir algumas responsabilidades.

Requisito do caso:

-Não-monorepo:

  • tem pacotes com links simbólicos
  • pacote com link simbólico exportou componente usando ganchos
  • criando páginas do lado do cliente de reação

    • Se estiver trabalhando em um monorepo

  • pacotes com links simbólicos
  • pacotes têm versões diferentes de dependências (até mesmo diferença de versão de patch), então até mesmo o espaço de trabalho será resolvido quando 2 react instalados
  • pacote de entrada importou um pacote com link simbólico que usa ganchos

Exemplo

Estrutura

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

Depois de inicializar com espaços de trabalho, ele resolverá

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

E uma vez que você servir ProductA com webpack ou talvez outra coisa, ele conterá 2 instâncias de reação.

Código no ProductA, procurará ProductA/node_modules/react .

Mas o ComponentWithHooks importado procurará mono repo root/node_modules/react .

Por quê? Lembre-se das regras de pesquisa do npm? Se não conseguir encontrar o módulo em sua própria pasta node_modules, ele procurará os node_modules do pai...

Portanto, ferramentas como o webpack aplicaram essa regra por padrão perfeitamente.
Não há nada de errado com a solução de repo mono util se tornar popular.
E o pacote normal não notará isso, pois a maioria deles não requer uma única instância como react e redux.

Estou tendo esse mesmo problema usando uma reprodução muito básica usando o exemplo de espaços de trabalho de fios - https://github.com/mwarger/yarn-workspace-hooks-repro

Eu tenho um component-library que está escrito em datilografado e empacotado com parcel. O example-demo é o que mostrará este component-library e é um aplicativo CRA recém-criado. Todos os pacotes comuns são içados com fios, então, em teoria, deve haver apenas uma versão do react disponível. No entanto, a chamada React.useEffect que estou fazendo no index.tsx causa o erro que me leva a esse problema do GitHub.

Tudo funciona até que um gancho seja adicionado. Para reproduzir o erro, remova o comentário das linhas 7-9 em component-library/src/index.tsx

Espero estar fazendo algo bobo que esqueci. Por favor, informe sobre quaisquer passos que eu possa usar para tentar remediar isso. Obrigado!

Edição de acompanhamento: A saída do script de depuração sugerida abaixo imprime true para mim. Parece que não tenho dois Reacts.

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

Levei várias horas, então pode valer a pena tomar uma nota aqui.

No meu caso, coloquei uma linha de <script defer src="./dist/bundle.js" /> no cabeçalho do template HTML, que funciona normalmente quando não estou usando hooks React. Todas as soluções não funcionam e a verificação window.React1 == window.React2 retorna true neste caso.

Como o webpack injetará a tag de script posteriormente, o modelo não deve ter a tag de script por conta própria. Remova a tag script do template e torne o React funcional com hooks (trocadilho intencional) novamente.

No meu caso, eu tenho um aplicativo React que estava npm vinculado a uma dependência em que eu estava trabalhando. Isso fará o truque até que eu possa corrigir algumas dependências que precisam mover react e react-dom para dev e peer deps.

  1. Do aplicativo: cd node_modules/react && npm link
  2. Do aplicativo: cd node_modules/react-dom && npm link react
  3. Do pacote vinculado: npm link react

Por que funciona? A página de aviso de erro menciona que "para que os Hooks funcionem, a importação de reação do código do aplicativo precisa resolver para o mesmo módulo que a importação de reação de dentro do pacote react-dom".

Ainda estou com esse problema, apesar de tentar todas as opções acima. Configuração padrão do webpack4/babel, com plugins preset-env e preset-react . Minhas versões react/react-dom são fixadas em 16.8.4 usando as resoluções yarn (onde também a verificação window.React1 === window.React2 acima retorna true ).

Isso é no mais básico dos usos:

import React, { useState } from "react";

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

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

Alguém tem alguma outra ideia?

EDIT: Para esclarecer, o erro é mostrado como react.development.js:88 Uncaught Invariant Violation: Hooks can only be called inside the body of a function component. conforme o OP

No meu caso, eu tenho um aplicativo React que estava npm vinculado a uma dependência em que eu estava trabalhando. Isso fará o truque até que eu possa corrigir algumas dependências que precisam mover react e react-dom para dev e peer deps.

  1. Do aplicativo: cd node_modules/react && npm link
  2. Do aplicativo: cd node_modules/react-dom && npm link react
  3. Do pacote vinculado: npm link react

Por que funciona? A página de aviso de erro menciona que "para que os Hooks funcionem, a importação de reação do código do aplicativo precisa resolver para o mesmo módulo que a importação de reação de dentro do pacote react-dom".

Obrigado! Isso funciona muito bem para mim. (mesmo quando eu uso npm link e symlink situação mista)

Eu tentei todos os sugeridos acima e ainda estava tendo o erro.

Com uma pequena ajuda de @inverherive descobrimos que enzyme-adapter-react-16 ainda estava causando problemas.

Embora tenhamos atualizado react-test-renderer para a versão mais recente (16.8.4), pois só recentemente adicionou suporte a ganchos, descobrimos via npm ls react-test-renderer que a versão mais recente de enzyme-adapter-react-16 (1.11.2 ) tinha uma dependência interna de [email protected] , que não suporta ganchos.

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

Para corrigir esse problema, além de seguir as correções de @chulanovskyi , como estamos usando yarn, adicionamos react-test-renderer resoluções ao nosso package.json. Isso força todas as referências de react-test-renderer a usar "16.8.4".

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

Isso foi mega frustrante, espero que isso possa ajudar alguém. Obrigado a @chulanovskyi e @theKashey por suas sugestões também.

Isso fará o truque até que eu possa corrigir algumas dependências que precisam mover react e react-dom para dev e peer deps.

@ajcrews (eu posso ter perdido alguma coisa, mas) eu npm link uma biblioteca interna e essa biblioteca tem react em peerDependencies e devDependencies e eu ainda precisava do seu corrigir independentemente de resolver o erro. Belo achado!

Eu ia postar mas encontrei uma solução

Eu tenho uma biblioteca de componentes, com um aplicativo CRA de exemplo para desenvolvimento

No package.json do aplicativo CRA eu tive que modificar react e react-dom para "emprestar" do package.json do componente raiz

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

Isso foi mega frustrante, espero que isso possa ajudar alguém. Obrigado a @chulanovskyi e @theKashey por suas sugestões também.

@Paddy-Hamilton Sempre verifique seu arquivo de bloqueio após a instalação. Eu encontrei o mesmo problema em que yarn estava duplicando react-test-renderer . Com um pouco de cirurgia em seu arquivo de bloqueio, você pode corrigir esses:

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"

Um yarn check já te avisaria

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

em seguida, desduplique-o manualmente aplicando o seguinte patch:

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

Agora você tem uma única versão de react-test-renderer sem nenhum alias resolutions ou webpack .

Para quaisquer problemas relacionados a pacotes vinculados e create-react-app siga facebook/create-react-app#6207

Há muitas maneiras de resolvê-lo, e as resoluções de fios geralmente não ajudariam - está mais relacionado à "ferramenta de construção"

  • para webpack use aliases - apenas um alias "difícil" tudo se desvia como react para um único arquivo
  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 brincadeira use moduleNameMapper
"jest": {
    "moduleNameMapper": {
      "^react$": "<rootDir>/node_modules/$1",
    },

Isso fez isso por mim.

@ajcrews
Obrigado! Funciona brilhantemente para mim!

Fiz um pequeno caso de teste com configuração mínima usando react 16.8.6, electron-webpack e RHL. Notavelmente, quando esse erro ocorre, todo o navegador (nesta configuração, elétron) começa a usar um monte de tempo de CPU)

https://github.com/PerfectionCSGO/reeee

Eu tenho batido minha cabeça sobre este problema por 3 dias agora. Originalmente, pensei que o RHL fosse o problema, mas removê-lo inteiramente deste projeto não resolverá o problema.

npm ls react retorna apenas um resultado. Assegurei que a correção acima seja aplicada com as versões mais recentes + alias do webpack.

O código funcionará em um sandbox.

Em um webpack/site simples o código funcionará sem problemas. No entanto, com o electron-webpack esse 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 alguém possa me dar uma dica...

Quando eu substituo react-l18next por mobx-react-lite e uso observador, isso causará o mesmo efeito.

Em relação ao meu problema, resolvi-o dando uma cotovelada no electron-webpack e optando por uma solução de elétron mais 'pura'. Meu palpite é que é uma cadeia de ferramentas usada no webpack ou babel que é incompatível.

Eu encontrei esse problema apenas na produção. Nenhuma das soluções propostas aqui ajudou.
Meu caso de uso foi um aplicativo de terceiros que carrega como um widget em outro site.
Quando o site foi carregado pela primeira vez com o widget, tudo funcionou bem, mas quando o usuário navegou para uma página diferente e retornou à página com o widget, recebi o erro de ganchos.

Observe que o erro ocorre apenas quando a navegação não causa o recarregamento da página.

Passei horas tentando descobrir qual era o problema. Por fim, o problema estava no snippet de código que carrega o pacote de aplicativos. Na mudança de página, o pacote pode ser carregado várias vezes, o que causou, eu acho, várias instâncias do React no mesmo namespace.

Eu consertei verificando se o script já foi carregado.
Primeiro, exportei minha biblioteca para o namespace global usando a configuração de 'biblioteca' do Webpack:

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

E então no script de carregamento verifiquei se a biblioteca existe ou não:

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

Pode ser um caso de uso muito específico, mas espero que isso possa ajudar alguém.

Portanto, temos um aplicativo React principal aproveitando o webpack.
Estamos tentando criar uma pequena biblioteca React que usa hooks, tentamos trocar os bundlers (parcel, pure babel, webpack).
Ao testar nossa implementação de webpack, marcamos react e react-dom como externos, então não vamos incluí-los em nosso pacote.
Ainda temos a mesma exceção de ganchos ao usar o link npm.

Criar um link simbólico para o react do aplicativo principal funciona, mas não é um ótimo fluxo de trabalho de desenvolvimento.

Estou tendo dificuldade em descobrir a causa subjacente do problema. O que está produzindo uma instância React duplicada?

Oi @adriene-orange , você pode encontrar minha postagem https://github.com/facebook/react/issues/13991#issuecomment -472740798 para obter mais explicações.

A multi-instância causada pelo link npm ocorre porque o node, por padrão, procurará nos node_modules da pasta pai para o módulo se ele não puder encontrar em seu pacote.

A solução mais simples e melhor que encontramos para isso está na configuração do webpack do seu pacote de entrada (ou outras ferramentas), há algo como resolve.modules para definir manualmente os caminhos e ordenar os caminhos que o webpack procurará pelos módulos. Exp., resolve: { modules: [path.resolve(PACKAGE_ROOT, 'node_modules'), 'node_modules'] } , forçará o webpack a encontrar os módulos no node_module da raiz do seu pacote de entrada primeiro. Se não conseguir encontrar o módulo na raiz, encontre na pasta node_modules relativa ...

Portanto, temos um aplicativo React principal aproveitando o webpack.
Estamos tentando criar uma pequena biblioteca React que usa hooks, tentamos trocar os bundlers (parcel, pure babel, webpack).
Ao testar nossa implementação de webpack, marcamos react e react-dom como externos, então não vamos incluí-los em nosso pacote.
Ainda temos a mesma exceção de ganchos ao usar o link npm.

Criar um link simbólico para o react do aplicativo principal funciona, mas não é um ótimo fluxo de trabalho de desenvolvimento.

Estou tendo dificuldade em descobrir a causa subjacente do problema. O que está produzindo uma instância React duplicada?

Oi estou recebendo este erro

Violação invariável: chamada de gancho inválida. Hooks só podem ser chamados dentro do corpo de um componente de função. Isso pode acontecer por um dos seguintes motivos:
1. Você pode ter versões incompatíveis do React e do renderizador (como React DOM)
2. Você pode estar quebrando as Regras dos Ganchos
3. Você pode ter mais de uma cópia do React no mesmo aplicativo
Consulte https://fb.me/react-invalid-hook-call para obter dicas sobre como depurar e corrigir esse 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 exemplo https://stackblitz.com/edit/react-mbze9q

Quando tento acessar esta função dentro dos casos de teste, estou recebendo o erro acima

@abhishekguru Você está chamando o Hook fora de um componente aqui em seu teste:

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 o erro indica, os ganchos só podem ser chamados de outro gancho ou de dentro de um componente. No seu caso, você pode criar um componente para seu teste e renderizar esse componente que usa o gancho, se desejar.

Plugue sem vergonha

@abhishekguru se você tiver um gancho genérico usado entre vários componentes e quiser testá-lo independentemente de qualquer componente específico, considere 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);
});

Eu queria entrar aqui porque tivemos problemas apenas com SSR. Limpamos require.cache do nó nas alterações de arquivo. Isso efetivamente fornece recarga a quente no servidor. Limpar require.cache do nó causará problemas com bibliotecas que precisam ter uma única cópia. Aqui está a nossa solução:

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

Nossa função isSingleton contém a lista de bibliotecas que devem ter uma única cópia. Uma boa regra geral é qualquer biblioteca que precise ser definida em peerDependencies

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

Também tive o mesmo problema e para mim

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

também retornou true , tentei todas as sugestões fornecidas, mas nada funcionou. Finalmente descobriu-se que:

O Webpack adiciona a tag de script com bundle.js no index.html automaticamente. Meu problema era porque eu estava adicionando bundle.js em index.html explicitamente , que costumava funcionar bem antes dos ganchos.

Para mim, o problema foi após a atualização do babel 7, não havia versões separadas com npm ls react. Removendo
"react-hot-loader/babel" de .babelrc corrigiu o problema temporariamente.

Eu tentei todas as soluções acima, mas ainda recebi o erro.
Eventualmente, descobri que foi causado pelo pacote why-did-you-update , e há um problema relacionado a ele. Apenas uma pista para quem usa um pacote semelhante que modifica o React.

Consegui consertar isso em um cenário react-native + Yarn Workspaces .


Na raiz package.json

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

Isso evita que o código react-native seja içado (como é necessário para reagir nativo), enquanto ainda iça react , fazendo com que todos os módulos compartilhados usem o mesmo react.


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

A configuração do metro permite que o empacotador saiba onde está tudo.

Eu encontrei uma maneira de resolver o problema para pessoas que estão desenvolvendo localmente um pacote npm, por exemplo, e estão tentando testá-lo localmente carregando seu pacote usando o link npm em algum tipo de aplicativo de exemplo.

Mudei de aplicativo de exemplo (forma original de testar o componente) para Storybook . Ao usar o storybook no projeto, ele não carregará o React duas vezes, pois usará o mesmo que o componente está usando. Ao usar o link npm, tive problemas com hooks e o React sendo carregado duas vezes, também não consegui fazer com que nenhuma das soluções acima funcionasse. Então o Storybook resolveu meu problema, e agora eu tenho uma maneira de testar meu componente através de vários cenários e ao mesmo tempo construir alguma documentação interativa para ele.

Compartilhando minha experiência com isso, resolvi para o nosso projeto usando externos do webpack para a biblioteca de componentes para excluir react e react-dom da compilação.

Estamos apenas começando com React. No meu caso, estamos começando com o Lerna monorepo com o pacote de biblioteca de componentes Neutrino e o pacote cliente Neutrino webapp. O webapp consome o produto de compilação da biblioteca de componentes vinculados. Depois de experimentar e obter true para a mesma instância do React, procurei uma maneira de excluir react e react-dom da compilação da biblioteca de componentes.

Parece uma solução de padrão de design comum para bibliotecas de componentes do webpack, portanto, na biblioteca de componentes, adicionei à configuração do webpack:

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

Não precisei colocar uma tag de script global no pacote webapp para react e react-dom . Eu estou supondo que o Webpack está fornecendo aqueles para a biblioteca de componentes em sua implementação require da mesma forma que fornece para o webapp.

outra causa deste erro é configurar incorretamente o Route do React Router,

Isso falha :

<Route render={MyHookedComponent}/>

, mas isso é bem- sucedido :

<Route component={MyHookedComponent}/>

Por exemplo. você precisa usar component não render . Este é um erro fácil de cometer já que render geralmente funciona bem com componentes baseados em classes.

Eu estava trabalhando no biolerplate e quero publicá-lo no npm, e desenvolvendo com a ajuda do npm link Estava funcionando corretamente mas depois de um tempo começou a dar erros Invalid Hook call warning .
Eu tentei usar o link npm ../myapp/node_modules/react mas não resolve meu problema,
E comparado React1 === React2 é verdade assim como npm ls react também feito, mostra apenas um pacote.

E eu não estou usando o webpack também, estou apenas adicionando alguma camada fora do create-react-app, então não posso forçar meu aplicativo a usar o módulo react instalado localmente.
Preso com ele nos últimos 3 dias._

O mesmo que @hnagarkoti .

Eu experimentei esse aviso durante a renderização do lado do servidor (SSR) porque eu estava usando uma versão mais antiga de react-apollo então só queria deixar este link aqui para ajudar a próxima pobre alma que se deparar com esse problema:

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

Resumindo, getDataFromTree não suporta ganchos de reação até a versão [email protected] .

Eu tive o mesmo problema e resolvi adicionando:

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

para a propriedade resolve na configuração do webpack do meu aplicativo principal.

Obviamente foi um erro meu usar duas cópias do React, mas concordo que seria ótimo se a mensagem de erro fosse melhor. Acho que talvez seja semelhante a: #2402

Alguma sugestão para fazer isso com create-react-app?

^ Ok, a solução que eu encontrei para resolver isso para create-react-app é usar react-app-rewired e customize-cra.

Aqui está meu config-overrides.js :

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

const path = require('path'); 

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

Projeto de exemplo: https://github.com/dwjohnston/material-ui-hooks-issue/tree/master

Em nossa equipe, temos um componente de navegação universal que funciona em dezenas de aplicativos, todos esses aplicativos vêm do react 15.0.0 para react 16.8.0, para permitir a navegação implementada acima dos ganchos, temos que agrupá-lo com um react mais recente

Neste caso, ter várias instâncias do react é um requisito fundamental para nós, gostaria de saber se a equipe oficial do react está disposta a resolver esse problema no futuro?

@dwjohnston minha solução para create-react-app foi criar uma configuração de webpack para desenvolvimento. create-react-app usa internamente webpack, webpack-dev-server e o babel-loader, então criar uma configuração de webpack apenas para desenvolvimento não foi tão ruim porque as dependências já estão implicitamente lá, mas ainda uma boa quantidade de sobrecarga para obter o funcionando corretamente.

Eu tenho um problema em create-react-app : https://github.com/facebook/create-react-app/issues/6953 para adicionar suporte ao webpack alias ou similar.

👋 Se alguém também estiver usando create-react-app e passando por esse ponto de dor, você poderia dar um sinal de positivo?

@ricokahler - Obrigado por apontar isso. Fico feliz em ver que não sou a única pessoa com esse problema - também o encontrei com contexto.

Existe algum recurso que você conheça que discuta mais essa questão?

Se você está no meu barco, você adicionou um pacote de componentes react de um diretório local, e agora ele automaticamente compila e instala, junto com sua própria cópia de node_modules (porque ele usa o link npm para fazer isso), dando seu app 2 cópias ou React agora.

Eu trabalhei em torno dele excluindo o node_modules//node_modules antes de executar o aplicativo. Para fazer isso automaticamente:

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

Eu também enfrentei isso ao fazer SSR.
Se você usa Lerna para testar localmente sua biblioteca React, pode adicionar "react/react-dom/react-router" como peerDependencies em sua biblioteca, mas não deve adicioná-los como devDependencies. (isso o torna duplicado)
Você pode usar node --preserve-symlinks para que ele possa pesquisar o repositório pai que instala o peerDependencies.
Para jest, você precisa adicionar o caminho do repositório pai à opção "jest.moduleDirectories" para que o Jest possa resolvê-los

@apieceofbart funciona para mim, obrigado!

Eu encontrei este erro ao carregar componentes React externos, por exemplo, com módulos JS. Eles estão completamente fora do projeto, carregados com dynamic import() (bem jsonp para mais suporte). Para contornar o problema, passamos/injetamos React como uma propriedade para cada módulo. Isso funciona, mas cada módulo depende do aplicativo React que o contém. Estamos tentando remover dependências.

Como outros já mencionaram, esta propriedade elimina o React como utilizável para qualquer tipo de micro front-end. O problema é que existe esse efeito colateral de criar um estado global no tempo de execução JS ao importar o React para usar como biblioteca.

Eu entendo que para casos de uso simples, ter esse efeito colateral significa que o React é "mais fácil de usar". Mas quando uma página da web é composta por vários scripts de várias etapas de pacote, um deles deve ser capaz de configurar o React (fazer esse efeito colateral explicitamente) e os outros podem simplesmente chamar funções de biblioteca.

Ainda tenho um problema com react-bootstrap: # https://github.com/react-bootstrap/react-bootstrap/issues/3965

Para qualquer outra pessoa tentando fazer uma lib para o React, tente https://github.com/whitecolor/yalc funciona muito melhor do que links simbólicos.

@mpeyper funciona bem. THX

@apieceofbart Isso funcionou para mim. Obrigado pela sugestão. 👍

Para mim, esse problema foi causado quando naveguei para o diretório do meu projeto no PowerShell e não capitalizei um nome de diretório no caminho. Criei o projeto em users/…/… em vez de Users/…/...
O problema foi resolvido quando consertei erros de capitalização e recriei o projeto.

Para mim, fazer:

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

Corrigi a maior parte, mas não foi suficiente, continuei recebendo o erro hooks can only be called inside the body of a function component .

Acontece que foi porque alguns dos componentes da minha biblioteca foram exportados assim:

export default Radium(withTranslation()(MyComponent))

:x:

Onde withTranslation é o HOC de react-i18next e Radium é o HOC de Radium.

E exportando-os assim:

export default withTranslation()(Radium(MyComponent))

:heavy_check_mark:
Corrigido tudo.

Observe que react-i18next estava na versão 10 que usa React Hooks

@mikeaustin Estamos com o mesmo problema. Você tem algum exemplo de "passar/injetar React como uma propriedade para cada módulo"?

Ainda com esse problema, tentei todas as etapas:

  • espaços de trabalho do yarn (via lerna)
  • verificado se existe um dep de reação, sim

Algumas coisas que podem ter impacto:

  • usando webpack com libraryTarget
  • usando texto datilografado
$ npm ls react-dom
/xxx
└── [email protected]

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

pacote raiz.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 Eu tive o mesmo problema e funcionou para mim, obrigado.

Adicione "prestart" em seu package.json como abaixo:

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

Eu tive esse problema e não foi devido a várias versões do react / react-dom
Nas ferramentas personalizadas que eu uso, o cache require estava sendo limpo (para um propósito fora desta discussão), por exemplo:

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

Então, para as pessoas por aí, se você estiver fazendo algo assim - isso afetará React Hooks, então evite-o se puder

Eu tive o mesmo problema e resolvi adicionando:

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

para a propriedade resolve na configuração do webpack do meu aplicativo principal.

Obviamente foi um erro meu usar duas cópias do React, mas concordo que seria ótimo se a mensagem de erro fosse melhor. Acho que talvez seja semelhante a: #2402

Para quem está usando o Parcel, se dist é onde estão seus arquivos compilados, você deve adicionar:

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

Para o seu package.json e então você ainda pode link (npm ou yarn) a biblioteca para desenvolvimento/teste local.

@mikeaustin Estamos com o mesmo problema. Você tem algum exemplo de "passar/injetar React como uma propriedade para cada módulo"?

Você pode usar o React Context para passar o "React" em si e criar um HoC para injetar a propriedade em cada componente. Você pode passar qualquer coisa em api como api.React, mas fica um pouco complicado envolver HoCs em torno desses componentes (porque agora eles estão disponíveis apenas dentro de um componente, não disponíveis para exportação.

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

Eu gasto algumas horas nisso, se alterar o código-fonte para alterar a mensagem de erro e adicionar mais informações não for fácil e você precisar de mais tempo, pelo menos adicione esta nota ao documento ,

_p.s: react tem uma ótima documentação, mas acho que essa página precisa de revisão._

@OliverRadini

Consegui corrigir isso atualizando react-hot-loader para ^4.6.0

Maaan, isso resolveu.
@gaearon @theKashey Que tal adicionar isso a https://reactjs.org/warnings/invalid-hook-call-warning.html para que as pessoas não percam tempo devido a uma versão mais antiga de react-hot-loader ?

Eu pensei que é muito bom documentado em uma dúzia de questões já.

Oi, estou usando o React em um aplicativo e uma biblioteca . Eu uso a biblioteca dentro do aplicativo. Consegui corrigir o problema de duas instâncias de reação usando:

Na configuração do webpack do aplicativo :

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

Na configuração do webpack da biblioteca

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

Então, estou enfrentando um problema ao chamar ganchos de um arquivo não 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;

Algum conselho, supondo que não seja "Mova para o arquivo JSX e transpile"?

Nada parece funcionar para mim, estou usando uma mistura de estímulo e reação, tenho um aplicativo híbrido, comecei a usar ganchos e falhou assim que comecei a adicionar turbolinks :(

Edit: por enquanto resolvi meu problema adicionando data-turbolinks-track="reload" data-turbolinks-eval="false" às tags de script que estou usando, então isso deve ser feito por enquanto

eu tenho a mesma pergunta, depois de 4 horas, eu fui encontrado que estava faltando jenkins util transform .babelrc files to server。。。

Por que isso criaria o erro?

$ 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, verifique qual é a sua versão do react-dom.

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

Eu enfrentei isso quando exporto um connect(mapStateToProps)(MyComponent) da biblioteca e uso essa biblioteca no meu aplicativo CRA.

Não, este foi o meu erro. A rotina que chamou isso usou react-router-dom e usou o prop render em vez do componente.

Algum de vocês teve o mesmo problema, mas com gatsby?

Eu recebo o seguinte resultado depois de 'npm ls react':
image

e 'npm ls react-dom'
image

No começo, pensei que havia instalado acidentalmente o react globalmente, depois de desinstalar globalmente, nada mudou. Então, tentei criar um projeto totalmente novo em um diretório diferente, 'gatsby new random-name' e adicionei um pequeno recurso (adicione comentários, seguindo para https://www.youtube.com/watch?v=asrdFuAxPaU&feature=youtu .be) para o gatsby-starter-default para testar se o erro se reproduziria. Bem, para meu desgosto, ele fez!

Todo e qualquer conselho seria bem recebido por um plebe frustrado.

Ainda estou enfrentando esse problema no livro de histórias. Essa saída do npm ls está correta ou não?
imageimage

No meu caso, o problema foi causado pelo módulo why-did-you-update .

Use o workspace e o lerna monorepo e levante o pacote. isso vai resolver o problema.

estamos tendo o mesmo problema com SSR. parece funcionar definindo externals: [“react”] em nossa configuração do webpack e carregando manualmente react/umd/react.development.js . isso é uma dor, no entanto, e adoraria encontrar uma maneira mais simples.

Ok, espero que isso ajude alguém. Estávamos carregando o webpack runtime.js várias vezes acidentalmente, o que fez com que várias cópias do React existissem. Certifique-se de carregar o runtimeChunk (runtime.js) apenas uma vez.

Se você tiver o problema com seus testes do Jest como eu, é isso que parece corrigi-lo para mim.
Adicione isso em seu jest.config.js

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

Seria bom se esse erro pelo menos apontasse para o arquivo onde está acontecendo. Eu acidentalmente chamei um gancho em uma função normal e foi difícil depurar.

Encontrei outra causa do problema e solução para ele.

Meu ambiente é electron e webpack mas isso também pode ajudar pessoas não eletrônicas. Passei dias dolorosos tentando resolver por que recebo essa mensagem de erro após atualizar para o React 16.9 (e React DOM 16.9).

No meu caso parecia que eu tinha dois Reacts no app, mas não consegui encontrar duas bibliotecas físicas em node_modules, nem mesmo usando npm ls react . Eu até usei webpack-bundle-analyzer para dar uma olhada no que está dentro do pacote.

Eventualmente, descobri que não tenho dois reacts fisicamente no projeto, mas React e React DOM foram referenciados/carregados duas vezes no arquivo HTML . Isso pode ser facilmente verificado adicionando, por exemplo console.log("React load") ao index.js da biblioteca React.

A fonte real foi conectada a electron-webpack . react e react -dom não foram marcados como externos , portanto, foram carregados no pacote, bem como posteriormente a partir de node_modules devido à necessidade de uso em algum outro módulo.

A solução foi tão simples quanto adicionar estas linhas a webpack.renderer.config.js :

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

Ok, então se alguém aqui usa parcel.js, por algum motivo estranho eu consegui fazer a seguinte importação: import React from 'React'; e uma vez que comecei a usar ganchos de reação, recebi o erro de violação invariável não percebendo que era porque eu estava importando incorretamente usando from 'React' em vez de from 'react' . Opa.

Algum de vocês teve o mesmo problema, mas com gatsby?

Eu recebo o seguinte resultado depois de 'npm ls react':
image

e 'npm ls react-dom'
image

No começo, pensei que havia instalado acidentalmente o react globalmente, depois de desinstalar globalmente, nada mudou. Então, tentei criar um projeto totalmente novo em um diretório diferente, 'gatsby new random-name' e adicionei um pequeno recurso (adicione comentários, seguindo para https://www.youtube.com/watch?v=asrdFuAxPaU&feature=youtu .be) para o gatsby-starter-default para testar se o erro se reproduziria. Bem, para meu desgosto, ele fez!

Todo e qualquer conselho seria bem recebido por um plebe frustrado.

Sim, eu encontrei o mesmo problema que você. Eu segui o conselho aqui ... ,

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

Eu adicionei React2 ao arquivo de índice em páginas. Ele retorna falso.

Desduplicado significa que o npm deveria ter desduplicado a dependência veja aqui...

O mesmo pacote não precisa ser instalado duas vezes! É apenas referenciado.

Além disso, ele move os pacotes "para cima da árvore" (achata a árvore). Isso faz todo o sentido, caso contrário, um pacote teria que procurar nos node_modules de algum outro pacote (o que seria meio confuso) e ajuda a simplificar as dependências.

Você pode validar isso, pois cada pacote em seu gráfico de dependência que diz desduplicado pode ser encontrado pelo menos mais uma vez no gráfico, geralmente em um "nível superior".

Embora evidentemente a desduplicação não tenha funcionado.

O que você tentou?

Estou recebendo este erro ao tentar construir com NextJS. Alguns componentes usam material-ui e o problema desaparece se eu removê-los. Eu não uso styled-components. Eu tentei excluir node_modules etc. sem sorte. Eu tentei adicionar aliases e resolve para react no meu arquivo next.config.js e package.json sem sorte. Estou usando react 16.8.6, react-dom 16.8.6 e next 9.0.4. npm ls diz que há apenas um de cada. Eu não estou usando nenhum link npm.

Repositório: https://github.com/dancancro/questions/tree/invalid-hook-call

Codesandbox está aqui: 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-call-inside-of-the-body-of-a-fun

O erro está aqui: https://gist.github.com/dancancro/2dfafb053aaaedfade406fd4f67eb68a
... render -> renderToString -> ReactDOMServerRenderer.read -> ReactDOMServerRenderer.render -> Object.WithStyles [como renderização] ...

O gancho incorreto é uma chamada useStyles() na linha 17428 do arquivo a seguir em uma função withStyles . Procure por "var classes = useStyles(props)". O problema é com o código gerado pelo nextjs. O código que escrevi não usa withStyles ou quaisquer ganchos ou funções que comecem com "use*"

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

ATUALIZAÇÃO: remover isso do meu next.config.js resolveu o problema:

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

Eu descobri uma solução excluindo react e react-dom da pasta node_modules $#$ do meu pacote vinculado.

Estou no mesmo barco que muitos de vocês. Tenho um pacote de biblioteca no qual estou trabalhando localmente e não quero ter o trabalho de publicá-lo sempre que precisar ver alterações no meu pacote de aplicativos. Eu vinculei e comecei a receber esse erro.

Aqui está a solução alternativa:

  • Pacote A: seu pacote de código de biblioteca, foi npm link 'd
  • Pacote B: seu pacote de código do aplicativo. Tem um link simbólico na sua pasta node_modules para o pacote A
  1. Construir pacote A. A mina produz seus ativos para dist/ , incluindo node_modules
  2. Na pasta node_modules distribuída do pacote A, exclua react e react-dom
  3. ???
  4. Lucro!

Observe que eu instalei a mesma versão do React nos dois pacotes. Você terá que reiniciar todos os processos em execução.

Remover why-did-you-update incompatível funciona para mim. (https://github.com/maicki/why-did-you-update/issues/52)

incompatível por que você atualizou

@bertho-zero use pode usar as novas devtools ou meu gancho useWhyDidYouUpdate

@brunolemos É ótimo, mas mais constrangedor, porque você precisa colocá-lo em cada componente.

A solução do @ dmart914 resolveu o problema para mim. Eu também tenho pacotes vinculados para que eu possa testar minha biblioteca sem publicar uma alteração... alguém encontrou uma solução alternativa para isso? Não é uma grande experiência publicar uma biblioteca de código aberto e ter que documentar a exclusão de pacotes NPM específicos para que os ganchos comecem a funcionar magicamente...

A solução para remover o módulo react do pacote vinculado não funciona se esse pacote tiver testes que exigem react (por exemplo @testing-library/react ou @testing-library/react-hooks ), portanto, parece que ainda precisamos de uma maneira melhor de lidar com isso.

Minha aplicação consiste em duas partes. A aplicação web principal e um módulo que é carregado dinamicamente na aplicação web. Tanto a aplicação web quanto o módulo usam React 16.9.0.
O módulo é carregado no aplicativo da web usando React.lazy() e a instrução dynamic import().
Quando o módulo é carregado, o erro "Chamada de gancho inválida" é lançado.

No meu caso, como o aplicativo principal e o módulo são construídos separadamente, eles não estão cientes um do outro e terão sua própria cópia do react. Eu tentei as seguintes sugestões encontradas no tópico, mas não resolvi o problema.

  1. Adicionando um alias no webpack.config do módulo que aponta para a reação do aplicativo principal como sugerido por apieceofbart .
    apelido: {
    react: path.resolve('../../node_modules/react')
    }

  2. Tentei apontar as dependências do react no package.json do módulo para o aplicativo principal.
    "dependências": {
    "react-dom": " file:../common/node_modules/react-dom ",
    "react": " file:../common/node_modules/react "
    }

Eu acho que o react tem que suportar a execução de várias cópias quando se trata de módulos carregados dinamicamente.

Com base em algumas das respostas acima, aqui está o que funcionou para mim:

  1. Adicionado o seguinte 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>
...

Depois disso, consegui executar ganchos na minha biblioteca usando o React carregado do CDN, enquanto o Jest ainda carregava a cópia do react do node_modules (instalado do devDependencies).

espero que ajude

Eu enfrentei esse problema quando tento alterar meu componente de funcional para componente classfull e também recebo esse erro, então aqui está minha solução em relação a esse erro, espero que ajude no seu caso também.

tente usar o componente de ordem superior neste caso

importe React de 'react';
importar PropTypes de 'prop-types';
importe { withStyles } de '@material-ui/styles';
importe o botão de '@material-ui/core/Button';

estilos const = tema => ({
raiz: {
background: 'gradiente linear (45 graus, #FE6B8B 30%, #FF8E53 90%)',
borda: 0,
bordaRaio: 3,
boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)',
cor branca',
altura: 48,
preenchimento: '0 30px',
},
});

class HigherOrderComponent estende React.Component {

render(){
const { classes } = this.props;
Retorna (
Componente de ordem superior
);
}
}

HigherOrderComponent.propTypes = {
classes: PropTypes.object.isRequired,
};

export default withStyles(styles)(HigherOrderComponent);

Estou usando o Yarn e consertei isso forçando a resolução no meu package.json :

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

Você adicionou o pacote Pai ou Filho?

Com base em algumas das respostas acima, aqui está o que funcionou para mim:

  1. Adicionado o seguinte 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>
...

Depois disso, consegui executar ganchos na minha biblioteca usando o React carregado do CDN, enquanto o Jest ainda carregava a cópia do react do node_modules (instalado do devDependencies).

espero que ajude

Sem ofensa, mas é preocupante que soluções como esta tenham de ser seguidas. Eu tenho tentado resolver esse bug nos últimos dois dias sem depender de tais hacks.

Estou trabalhando em uma biblioteca reutilizável que contém componentes usando ganchos. Preciso testá-los em projetos reais antes de publicá-los. A única solução para isso é usar yarn|npm link . Eu empacotar a biblioteca usando rollup e posso verificar se o pacote não contém uma versão de react. Quando eu empacotar (webpack) o aplicativo que faz uso da biblioteca, o bug/problema aparece. Isso acontece para aplicativos de create-react-app e next.js também. Ambos os frameworks usam webpack em segundo plano.

Alguém já encontrou uma solução sustentável?

Ao descartar npm|yarn link completamente, consegui resolver o problema. Em vez disso, eu uso esta linda biblioteca, que é independente da estrutura do seu projeto. Ele também permite que você continue usando o webpack como seu empacotador, para que você não precise declarar _react_ e _react-dom_ como external ou alias . Infelizmente, ele introduz alguns novos diretórios e arquivos de bloqueio para o projeto, mas ei, funciona... localmente e até mesmo dentro de nossos contêineres docker.

Talvez isso seja na lista um pouco útil:

Link

@GabrielBB obrigado, é trabalho para mim

@dmart914 obrigado! Até agora, a única solução alternativa que funciona para mim :)

Atualmente recebendo o aviso React Invalid Hook Call ao usar uma configuração mínima e direta.

Este componente de função:

  1. Usa a mesma versão para React e ReactDOM.
  2. Segue as Regras dos Ganchos.
  3. Só tem uma cópia do React.

__Dependências__
[email protected]
[email protected]
[email protected]
[email protected]

E correndo webpack test.js -o main.js para construir.

Espero que este arquivo:

  • Renderize a caixa.

    • Pause o depurador antes de chamar React.useState .

    • Crie um booleano test e atualize o retorno de chamada updateTest .

    • Lança o erro React.

    • Na renderização, execute os callbacks React.useEffect .

    • Lança o erro React.

Estou fazendo algo errado, ou há algo mais acontecendo?

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

Você esqueceu de realmente criar um elemento. Você está invocando Item() de forma síncrona antes de alcançar a chamada ReactDOM.render . Você precisa passar el(Item) .

Verdadeiro! Obrigado pela informação.

Estou em uma situação semelhante a alguns dos outros comentaristas. Estou usando o webpack para transpilar alguns componentes react (alguns dos quais usam ganchos) e colocando o código transpilado em uma pasta lib . Eu adicionei react ao campo externals da configuração do webpack para que ele não seja empacotado com o código do componente. Eu gostaria de usar esses componentes em dois projetos separados - esses componentes são comuns entre eles e, portanto, gostaríamos de desenvolvê-los em um só lugar e ter as atualizações refletidas em ambos os aplicativos.

Se a dependência for adicionada usando common-components: file:../../common-components/lib no package.json, os componentes serão carregados perfeitamente, no entanto, executar o webpack não atualiza os componentes imediatamente - em vez disso, devo executar yarn upgrade common-components e reiniciar o servidor dev.

Se a dependência for adicionada usando common-components: link:../../common-components/lib , a reexecução do webpack atualizará os arquivos no node_modules do aplicativo principal (já que está usando um link simbólico agora), mas estou recebendo o erro acima de várias instâncias de reagir. Suponho que agora esteja usando a versão react na pasta common-components/node_modules .

Existe uma maneira de usar links simbólicos (ou seja common-components: link:../../common-components/lib ), enquanto também garante que os componentes vinculados usem o react encontrado na pasta node_modules do aplicativo principal? Como estou planejando usar esses componentes em ambos os aplicativos, não posso vincular o pacote react de um deles à biblioteca de componentes comuns e gostaria de evitar vincular as reações dos dois aplicativos principais ao usado no pacote de componentes comuns. Eu vi alguns comentários referentes ao campo resolve do webpack que parece promissor, mas não consigo fazê-lo funcionar. Qualquer ajuda seria muito apreciada!

edit: para quem estiver interessado em nosso caso de uso, acabamos alterando a etapa de compilação para simplesmente copiar os arquivos nos dois projetos em que eles são necessários, evitando a transpilação por completo.

Uma solução rápida seria não publicar o pacote, mas apenas enviá-lo para o github e importá-lo para o seu projeto usando yarn add <git-url> .

Uma solução rápida seria não publicar o pacote, mas apenas enviá-lo para o github e importá-lo para o seu projeto usando yarn add <git-url> .

A razão pela qual muitos de nós usamos os caminhos relativos do link npm e do pacote npm é desenvolver e testar o código sem ter que publicar alterações no NPM ou no GitHub antes de sabermos que funcionará.

Encontramos esse problema relacionado a https://github.com/facebook/react/issues/13972#issuecomment -447599035, pois acho que isso também pode ser causado por um servidor Webpack'd Node. Nosso caso de uso foi um teste de integração rodando dentro do Jest que executou webpack() programaticamente para construir o servidor antes de executar os testes. A questão, acredito, está relacionada a como o ESM e o CJS podem existir ao mesmo tempo.

Tome este exemplo por exemplo:

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

O que estou vendo em uma sessão do depurador é que podemos obter duas instâncias diferentes do React na versão compilada deste arquivo:

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

Onde
_react é do ESM import React from 'react' neste arquivo
_react2 é do CJS var _react = _interopRequireDefault(require("react")); de dentro de node_modules/@apollo/react-ssr/lib/react-ssr.cjs.js

Eu acredito que isso fez com que a referência ao React não fosse igual nos dois lugares (arquivo de renderização do servidor e dentro do pacote @apollo/react-ssr ) e, assim, fez com que o erro fosse lançado.

Descobrimos que isso provavelmente foi causado pelo uso programático de webpack() de dentro do teste e refatoramos esses testes para serem testes de ponta a ponta. Lição sendo para nós que se o problema está acontecendo apenas no código de teste, você pode ter testes excessivamente complicados.

Consegui resolver com o fio:

cd para myApp/node_modules/react e yarn link

então na sua biblioteca, execute yarn link react

Agora sua biblioteca está usando exatamente a mesma versão react que seu aplicativo principal

Eu tentei definir reagir como uma dependência de peer na minha lib, mas a lib não compilaria

Como se pode corrigir isso usando create-react-app sem ejetar ou mudar para yarn ?

Você pode usar exatamente a mesma técnica usando o link npm. Não é necessário ejetar.

Vincular react não é a melhor ideia quando você trabalha em vários projetos com versões diferentes.

@woles você está totalmente certo, mas no meu caso, resolve meu problema de 'ganchos'. Espero que os desenvolvedores do react encontrem uma solução melhor

Oi,
Corrigi esse bug depois de horas percebendo que acidentalmente usei o componente falsamente dentro do roteador de reação.

Meu aplicativo estava funcionando, mas em um componente não consegui adicionar useState. o motivo foi que eu usei o componente dentro do método de renderização dos roteadores de reação sem a função de ordem superior como esta:
<Route exact path="/path" render={ ComponentCausingTheErrorMesage }/>
Mudando para
<Route exact path="/path" component={ ComponentNowWorkingAgain }/>
consertou pra mim

Eu estava usando npm link entre um aplicativo e um módulo em que estava trabalhando ativamente e tive que corrigi-lo vinculando os react e react-dom do aplicativo ao módulo e, em seguida, vinculando o módulo para o aplicativo:

no aplicativo:

  1. cd node_modules/react && npm link
  2. o mesmo para react-dom

no módulo:

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

no aplicativo:

  1. npm link [module-name]

Espero que isso ajude alguém

Tínhamos ganchos trabalhando no lado do cliente, mas estávamos atingindo esse erro no SSR. Meu colega resolveu isso com o seguinte em nossa configuração do webpack do lado do servidor:

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

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

Consegui resolver com o fio:

cd para myApp/node_modules/react e yarn link

então na sua biblioteca, execute yarn link react

Agora sua biblioteca está usando exatamente a mesma versão react que seu aplicativo principal

Eu tentei definir reagir como uma dependência de peer na minha lib, mas a lib não compilaria

Isso funciona simplesmente lindo

Acabei de encontrar esse problema, ao usar o electron-webpack, react e material-ui ao mesmo tempo. Quando tento usar qualquer coisa do material-ui - recebo este erro (por exemplo, tente usar o

Oi ZVER3D, tente ler meu comentário anterior. Espero que ajude!

Eu estava usando npm link entre um aplicativo e um módulo em que estava trabalhando ativamente e tive que corrigi-lo vinculando os react e react-dom do aplicativo ao módulo e, em seguida, vinculando o módulo para o aplicativo:

no aplicativo:

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

2. same for `react-dom`

no módulo:

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

2. `npm link`

no aplicativo:

1. `npm link [module-name]`

Espero que isso ajude alguém

Doce bebê Moses, isso me ajudou muito. Nem considerei o problema de serem versões diferentes do react!! Estou construindo um componente localmente para publicar no NPM, mas tenho um projeto separado para testá-lo localmente, usando o link npm. Obviamente (agora) ambos estão usando diferentes versões do react. D'oh!

Oi ZVER3D, tente ler meu comentário anterior. Espero que ajude!

Obrigado por me apontar na direção certa. Outra solução foi adicionar a biblioteca ui, que estou usando em "whiteListedModules". O único problema seria que você teria que fazer isso para todos os módulos que exigem reação para compilar.
Então, no package.json eu escrevi isso:

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

Estou desenvolvendo um aplicativo React usando a abordagem monorepo. Eu tenho um aplicativo principal ( brush ) e um componente de biblioteca de reação ( react-gbajs ).

Então, quando tento renderizar meu componente react-gbajs , tenho esse erro sobre várias instâncias do React. Se eu copiar e colar o mesmo código em brush não tenho nenhum problema.
Eu segui muitas abordagens para corrigi-lo, mas nenhuma delas resolveu (alterar compilação no Webpack, espaço de trabalho do Yarn, link npm ...)

Eu tentei depurar para verificar se eu realmente tenho duas cópias do React (usando console.log(window.React1 === window.React2) do doc do React), mas ele avalia como true !
(uma solução MUITO RUIM que estou usando agora é passar os ganchos como prop: <GBAEmulator useEffect={useEffect} /> ...

Alguém tem alguma ideia para consertar?

Meu projeto é de código aberto e estou adicionando este novo componente da biblioteca react neste branch: https://github.com/macabeus/klo-gba.js/blob/ac18f4d42b122c333622f502947135c2de217ce2/react-gbajs/src/index.js#L251 -L274

Olá a todos,

Tenho um aplicativo (myApp) que usa como dependência uma biblioteca personalizada (myDepPackage). Ambos estão usando o webpack como ferramenta de compilação e é claro que eu estava tendo o mesmo erro. Nenhuma das soluções acima funcionou para mim. O que ele fez foi forçar o webpack a NÃO incluir reagir no pacote final da biblioteca personalizada (myDepPackage). A única linha de configuração que tive que adicionar na configuração do webpack (do myDepPackage) é a abaixo:

externals: {
  react: "react",
},

Você pode aprender mais sobre a opção "externals" aqui: https://webpack.js.org/configuration/externals/#externals

@tsevdos Muito obrigado!!! ❤️
Resolveu meu problema que eu disse no comentário anterior.

Para nós, o problema era que temos um aplicativo React incorporável que é carregado na página a partir de um shortcode do WordPress e montado em um div com um ID aleatório. Em algumas páginas, temos vários aplicativos incorporados e estava funcionando bem até começarmos a usar ganchos.

Ele só reclamaria em páginas que possuem vários aplicativos incorporados, então a solução foi atualizar o shortcode do WP para carregar o script com a compilação apenas uma vez.

Parece simples e óbvio, mas foi difícil descobrir! Especialmente porque estava fazendo isso e funcionando bem até adicionarmos ganchos.

Curiosamente, em algumas páginas temos outros - diferentes - aplicativos que incorporamos que também estão usando ganchos, e eles carregam seu próprio script/compilação com React também,... mas então funciona muito bem! O problema era quando era exatamente a mesma compilação sendo carregada mais de uma vez e eles usam ganchos .

O que funcionou para mim foi uma combinação de duas sugestões deste tópico.

Configuração do webpack do aplicativo principal ( sugestão de @apieceofbart )

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

Configuração do webpack da dependência ( sugestão do @tsevdos )

  externals:
    react: 'react'
  }

Eu estava tendo esse problema com html-webpack-plugin e estava usando index.html parece com isso como uma configuração de template para 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>

Percebi que o plugin estava injetando <script type="text/javascript" src="main.js"></script> logo após <div id="root"></div> .

Então, quando abri a ferramenta dev e gerei o html ficou assim.

<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 mim, isso estava causando Invalid Hook Call Warning .

Consegui remover o aviso removendo <script src="main.js"></script> como abaixo.

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

</html>

Espero que ajude alguém que esteja procurando uma solução!

Esteja ciente de que as bibliotecas dependentes do React também podem causar esses problemas. No meu caso, eu estava usando versões diferentes de @emotion/core e @emotion/styled .

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

Oi,

Uma solução possível sem ejetar é misturar a solução de configuração de alias do webpack com as bibliotecas customize-cra e react -app-rewired . Dessa forma, você pode substituir apenas a configuração do webpack necessária para resolver o problema, criando um arquivo config-overrides.js com:

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

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

Eu tive esse problema em um site do Gatsby, executei o npm install e atualizei para a versão mais recente do Gatsby e corrigiu tudo

Se você está tendo problemas com o teste jest executando yarn or npm test (como eu estava) e está usando react-test-renderer , certifique-se de que react-test-renderer corresponda à mesma versão de react você está usando.

Exemplo:

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

Correr yarn add [email protected]

Eu tenho uma lib e verifiquei todas as versões de react e react-dom nos projetos lib e main. eles são exatamente os mesmos, mas não funcionaram.
No entanto, a solução @apieceofbart funcionou para mim.

@apieceofbart , você salvou meu dia <3

O que funcionou para mim foi uma combinação de duas sugestões deste tópico.

Configuração do webpack do aplicativo principal ( sugestão de @apieceofbart )

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

Configuração do webpack da dependência ( sugestão do @tsevdos )

  externals:
    react: 'react'
  }

Mesmo aqui. Eu preciso fazer essas duas correções para fazê-lo funcionar. Minha explicação é que a segunda configuração diz à dependência para usar o react externo com o nome 'react', e a primeira configuração aponta o nome 'react' para a pasta 'node_modules/react' no repositório principal. Portanto, ambos são necessários para fazer a ponte de reação funcionar.

Ainda assim, parece que para algumas pessoas um deles é suficiente, o que eu realmente não entendo.

O que funcionou para mim foi uma combinação de duas sugestões deste tópico.
Configuração do webpack do aplicativo principal ( sugestão de @apieceofbart )

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

Configuração do webpack da dependência ( sugestão do @tsevdos )

  externals:
    react: 'react'
  }

Mesmo aqui. Eu preciso fazer essas duas correções para fazê-lo funcionar. Minha explicação é que a segunda configuração diz à dependência para usar o react externo com o nome 'react', e a primeira configuração aponta o nome 'react' para a pasta 'node_modules/react' no repositório principal. Portanto, ambos são necessários para fazer a ponte de reação funcionar.

Ainda assim, parece que para algumas pessoas um deles é suficiente, o que eu realmente não entendo.

O segundo item é importante!
Se ignorado, no processo de compilação, o react será exportado junto, pois é uma dependência interna

muito amor @apieceofbart !!!! Eu estava prestes a chutar minha mesa pela parede

Portanto, ainda não há solução alternativa para microsserviços. Eu tenho aplicativo root com react que requer dinamicamente pacotes com outro react. Não podemos simplesmente usar a versão externa do react porque existem muitas equipes independentes com suas próprias dependências. Se nós os forçarmos a usar a mesma versão externa, a maioria dos projetos obviamente travará e será impossível atualizar esta versão, pois cada projeto dependerá dessa versão.

Alguma ideia?

Existe uma solução para usar ganchos de reação junto com o link npm, que não requer ejeção do CRA?

@tschellenbach
você pode usar o craco para substituir a configuração do CRA sem ejetar.
https://github.com/gsoft-inc/craco

Graças ao @tsevdos resolvi meu problema e fiz um tutorial de como criar um pacote React: https://youtu.be/esyS87NfBOw

Eu estava recebendo esse problema e a solução webpack não se aplicava porque estou usando o pacote bundler. Consegui corrigi-lo especificando um alias no package.json do meu aplicativo principal que se parecia com isso

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

Obtendo problemas ao tentar usar meus componentes React (escritos em ganchos) em um aplicativo de elétrons no mesmo projeto com um pacote json diferente. A estrutura do arquivo fica assim:

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

Ambos package.json incluem react e react-dom em package.json, mas são as mesmas versões e não estou vendo ele mostrar duas instalações react quando faço npm ls react . Alguma ideia?

EDIT: a solução de @ewan-m funcionou!

Então eu me deparei com um caso estranho, eu acho. Infelizmente, uma biblioteca de terceiros misturou componentes funcionais e baseados em classes. Meus componentes na minha base de código são funcionais. Um componente baseado em classe da biblioteca atua como um layout que renderiza meu componente como filho. Isso eu acredito que é o que está acionando o 'Erro: chamada de gancho inválida.' Como devo contornar isso para usar ganchos, preciso converter o meu em um componente de classe?

@GrandathePanda Misturar classes e componentes funcionais não deve importar. Se uma classe chama um funcional, que chama um gancho, não há problema nisso. A única coisa que você não pode fazer é chamar um gancho diretamente da classe.

Ok, @JeremyGrieshop , então ainda tenho alguma investigação a fazer, se eu renderizar sem usar o componente de terceiros, ele renderiza bem, então há algum conflito entre essa biblioteca e meu código. Se eu tivesse que adivinhar que eles estão usando uma versão de reação diferente, talvez em seu pacote.

Ok, @JeremyGrieshop , então ainda tenho alguma investigação a fazer, se eu renderizar sem usar o componente de terceiros, ele renderiza bem, então há algum conflito entre essa biblioteca e meu código. Se eu tivesse que adivinhar que eles estão usando uma versão de reação diferente, talvez em seu pacote.

Certo, verifique npm ls react react-dom do seu aplicativo para ver se há várias versões. É possível que a biblioteca de terceiros tenha uma dependência com uma versão específica.

@JeremyGrieshop Parece que meu aplicativo está usando 16.12.0 para reagir e dom e o terceiro (pesquisa elástica-ui) usa 16.8.0 para reagir e dom. Se eu estiver correto, o problema é que, como minha biblioteca de terceiros 16.8.0 está renderizando o componente criado com 16.12.0, isso causará o problema? Eles também são um monorepo de lerna que potencialmente complica ainda mais depois de ler todos os comentários acima. O problema está surgindo de um gancho useStyles criado no materialui, eles fornecem um withStyles hoc para compatibilidade com versões anteriores e acho que enquanto isso vou seguir esse caminho. Todas as mudanças no webpack e/ou no pacote json mencionados acima realmente parecem um bandaid que é mais suscetível a quebrar do que apenas ir com um hoc clássico enquanto os ganchos descobrem como amadurecer diante de tantos problemas de implementação diferentes.

@GrandathePanda IMHO, suas opções são (1) fazer com que o terceiro atualize sua dependência de reação para 16.12 ou decida se tê-lo como peerDependency é mais adequado do que uma dependência; (2) Use 16.8 em seu aplicativo para que eles compartilhem as mesmas versões de lib; (3) Elimine a cópia do react com:

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

O comando acima pode ser colocado em um "prebuild" e "prestart" na parte "scripts" do seu package.json (que é o que estou fazendo atualmente). A desvantagem de (3), suponho, é se eles estão usando qualquer coisa obsoleta entre 16.8 e 16.12.

Olá a todos,

Tenho um aplicativo (myApp) que usa como dependência uma biblioteca personalizada (myDepPackage). Ambos estão usando o webpack como ferramenta de compilação e é claro que eu estava tendo o mesmo erro. Nenhuma das soluções acima funcionou para mim. O que ele fez foi forçar o webpack a NÃO incluir reagir no pacote final da biblioteca personalizada (myDepPackage). A única linha de configuração que tive que adicionar na configuração do webpack (do myDepPackage) é a abaixo:

externals: {
  react: "react",
},

Você pode aprender mais sobre a opção "externals" aqui: https://webpack.js.org/configuration/externals/#externals

@tsevdos eu te amo. Você acabou de acabar com alguns dias de intenso aborrecimento. Obrigada.

Olá a todos,

Estou tentando usar um gancho em um componente, este componente deve ser exportado de gatsby-browser.js .

Qual é o comportamento atual?

Estou recebendo este erro:

Rejeição não tratada (erro): chamada de gancho inválida. Hooks só podem ser chamados dentro do corpo de um componente de função. Isso pode acontecer por um dos seguintes motivos:

  1. Você pode ter versões incompatíveis do React e do renderizador (como React DOM)
  2. Você pode estar quebrando as regras dos ganchos
  3. Você pode ter mais de uma cópia do React no mesmo aplicativo
    Consulte https://fb.me/react-invalid-hook-call para obter dicas sobre como depurar e corrigir esse problema.

Este é um código de exemplo:

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;

Qual é o comportamento esperado?

Hook deve ser executado sem erros, ou mensagens de erro úteis devem ser fornecidas.

As versões das dependências react e react-dom são 16.12.0

@leejh3224 muito obrigado cara! depois de horas de pesquisa, encontrei esta resposta, resolveu meu problema.
Acabei de alterar a configuração do HtmlWebpackPlugin de
inject: true para inject: 'head' e os erros de reação reduzidos desapareceram.

Eu criei uma pergunta stackoverflow com minha experiência de tentar fazer isso funcionar. Seria possível, para quem conseguiu fazer isso funcionar, dar uma olhada e dar alguns conselhos?

Estou portando um aplicativo jquery para React. Eu tenho um utilitário para expor componentes React dentro do jQuery chamado asJqueryPlugin . Aqui está o arquivo:

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

O aplicativo tem muitos pontos de entrada no Webpack, e cerca de 3-4 componentes estão usando essa técnica agora. Quando os componentes são agrupados em diferentes pacotes de ponto de entrada, acredito que é quando o problema acontece.

Então, se eu tiver dois pontos de entrada no Webpack:

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

Então, em cada um desses arquivos, configuramos um componente exposto (cada um 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

Agora, se eu incluir as duas entradas na mesma página e tentar renderizar os dois componentes por meio do plug-in jquery ...

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

... Eu recebo este erro de ganchos.

Não tenho certeza se isso ajuda a conversa ou não, mas pelo menos mostra um caso de uso de como um (questionavelmente) dev sensato pode se colocar em uma situação com várias instâncias de reação.

Isso me ajudou - https://github.com/facebook/react/issues/13991#issuecomment -554928373
Mas também tive que remover react e react-dom das dependências e movê-los para dependências de pares e desinstalar e reinstalar módulos de nó.

Oi,
Eu li a conversa e muitos posts na web e ainda estou preso com o erro de várias instâncias de reação.
Eu empurro este repositório para reproduzir o bug: https://github.com/jeromelegrand/dooliz-lib
Espero que alguém possa me ajudar.
Obrigado.

Estou enfrentando esse problema e não chego a lugar nenhum com as soluções acima.
Resumindo: estou muito certo de que tenho apenas uma versão react em execução e recebo o erro usando react-bootstrap, que provavelmente não usa ganchos errados, porque ninguém mais tem problemas.

Este erro ocorre em um back-end node.js para mim.

__O que eu verifiquei nas versões de reação__

Eu tenho uma configuração de fios com espaços de trabalho, yarn list react ou yarn list react-dom mostra apenas uma instância.

Eu imprimi require cache para ver o que foi importado:

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

Eu o executo antes de renderizar algo do react-bootstrap, o que causa o erro de gancho inválido para mim, e ele 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

O que parece confirmar que há apenas 1 versão de reação carregada.

Finalmente, adicionei isso a node_modules/react-dom/index.js

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

E isso para 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

Alguma ideia do que mais pode ser isso?
Também postarei isso no repositório react-bootstrap.

Portanto, tenho certeza de que ter duas instâncias do React não é o problema aqui. Eu acho que o problema é quando há dois react _roots_. Você está ligando ReactDOM.render() várias vezes em diferentes partes da página? Se sim, acho que isso pode causar o problema. Acho que os ganchos "pertencem" a uma "raiz" específica e quebram quando há vários deles e os dois pacotes compartilham algum código comum. Estou supondo aqui...

... Acho que o problema é quando há dois react _roots_. Você está ligando ReactDOM.render() várias vezes em diferentes partes da página?

Obrigado @timkindberg isso me ajudou a finalmente resolvê-lo. Percebi que estou usando react-tree-walker para fazer uma renderização inicial e buscar os dados necessários antes de fazer a renderização final com ReactDOMServer.renderToString

Remover rapidamente o uso deste pacote removeu o erro, e agora tenho a mesma coisa trabalhando com react-ssr-prepass , que na verdade agora é recomendado na página readme react-tree-walker

Então foram duas ligações ReactDOM.render ! Por enquanto, essa configuração com react-ssr-prepass funciona para mim, e quando o Suspense chegar em react-dom/server, posso mudar para isso

Estou usando react-compare-image https://github.com/junkboy0315/react-compare-image no meu projeto Gutenberg, mas tendo esse problema estranho, embora tudo funcione sempre que eu removo o componente ReactCompareImage da função salvar. A função de edição funciona perfeitamente, mas o save não funciona.

Eu passei por https://reactjs.org/warnings/invalid-hook-call-warning.html e acho que não tenho nenhum desses problemas.

Aqui está o arquivo completo da função de salvamento:

```inspetor de importação de "./inspector";
import { Fragmento } de "reagir";
importe ReactCompareImage de "react-compare-image";

/**

  • Dependências do WordPress
    */
    const {__} = wp.i18n;

const salvar = ({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 salvamento padrão;
```
Screenshot 2020-02-19 at 4 11 52 PM

Também estou me deparando com esse problema. Eu tenho uma recapitulação postada no SO: https://stackoverflow.com/questions/60331304/next-js-with-typescript-invalid-hook-call-hooks-can-only-be-call-inside-of-t

Eu também tenho um exemplo reproduzível mínimo: https://github.com/coler-j/shopify_playground

Meu aplicativo principal é um aplicativo create-react (não ejetado) que estava importando uma biblioteca compartilhada que também usava React. Consegui resolver isso por:

Usando o Rollup para empacotar a biblioteca em vez do webpack
Por alguma razão que ainda tenho que descobrir, o uso de externals não removeu o React do pacote da 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(),
    ],
  },
]

Instalando o craco e usando isso para modificar o webpack do aplicativo principal
craco.config.js

const path = require('path')

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

Obrigado a @arminyahya por me indicar Craco.

Estou tentando usar ganchos durante o carregamento do react de um cdn. Este exemplo (esta é a página html inteira) dá o erro Hooks can only be called inside of the body of a function component quando Example() é chamado. Eu removi tudo, até mesmo o ReactDOM, então é difícil imaginar que eu poderia ter várias cópias do React. Isso é simplesmente impossível?

<!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 Isso é porque você tem ZERO raízes de reação. Você precisa renderizar seu aplicativo. No entanto, esta ainda é uma boa confirmação de que os ganchos dependem (e são acoplados) a uma raiz de reação.

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

Obrigado! Na verdade, não era a falta de uma raiz de reação - acabei de removê-la ao simplificar o erro o máximo possível - mas algo igualmente idiota: Em vez de <Example /> , eu estava apenas escrevendo Example() . Não é a mesma coisa, em tudo. Obrigado novamente.

Nada parece funcionar para mim. Estou criando um componente para compartilhar e usar em outros projetos, mas ao testar localmente de outro projeto não funciona. Estou usando Hooks com 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',
    }),
  ]}

Alguma sugestão? Testei todas as sugestões de discussões antigas.
Obrigado! :sorriso:

Eu declarei um Settings.js da seguinte forma:

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

Eu importo e uso no App.js da seguinte forma:

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

Mas eu recebo:

Screenshot 2020-02-27 at 22 27 01

Estou usando:

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

O que há de errado?

Você está chamando seu componente Settings como uma função e não como um componente de função.

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

Hooks não são permitidos dentro de funções simples, apenas em componentes de função e a forma como você está chamando isso faz o React pensar que seu componente é na realidade uma função normal.

Talvez isso poupe a dor de cabeça de alguém, se você estiver usando react-router-dom se você passar seu componente em render assim (não da maneira correta), ele dará Invalid Hook Call Warning
<Route path="/:cuid/:title" render={PostArticle} />

Levei meia hora para saber onde errei

Isso pode ajudar alguém - se você estiver enfrentando esse bug depois de usar react-router-dom, verifique como você definiu suas rotas. por exemplo, deveria ser <Route path={'/upgrade/:plan'} exact children={<Upgrade />} /> enquanto eu estava fazendo <Route path={'/upgrade/:plan'} exact children={Upgrade} />

Isso é especialmente estranho se você estiver usando tinta ou pastel para criar uma CLI (consulte https://github.com/vadimdemedes/pastel/issues/2). Não posso torná-lo um peerDep porque não posso pedir a todos os usuários que instalem o React e também não posso forçá-los a usar uma determinada versão / intervalo do React.

Minha equipe está usando o Yarn e estava recebendo o erro Invalid hook call apenas nos testes, não no aplicativo. O problema era que react-test-renderer estava resolvendo para uma versão menor que react e react-dom , então adicionamos resolutions em package.json :

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

Para pessoas que usam Gatsby em um subdiretório, esta é uma solução possível.

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

Eu tenho o mesmo problema ao executar o comando npm link ,há um problema

Então eu usei a solução oficial fornecida pelo react para resolver este problema

Esse problema também pode surgir quando você usa o link npm ou um equivalente. Nesse caso, seu bundler pode “ver” dois Reacts – um na pasta do aplicativo e outro na pasta da biblioteca. Supondo que myapp e mylib sejam pastas irmãs, uma possível correção é executar npm link ../myapp/node_modules/react de mylib. Isso deve fazer com que a biblioteca use a cópia React do aplicativo.

Se A precisa apresentar B (A e B são irmãos)

  • passo 1 (em B)

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

    • npm link

  • passo 2 (em A)
    npm link B

funciona para mim

Mesmo com essas respostas, não tenho certeza do motivo pelo qual estou recebendo o erro. Eu tenho minha biblioteca de dependências vinculada ao meu aplicativo principal e depois que recebi o erro, segui o react-docs e vinculei a versão da minha biblioteca de dependências ao react do meu aplicativo (executando npm link <>/webapp/node_modules/react . (até fiz isso com react- dom). Quando eu loguei para testar se React1 e React2 eram iguais, ele registrou true então eu não estava usando versões duplicadas do React, eu estava usando as mesmas versões do React e estava usando componentes de função Então, mesmo que o log de teste indicasse que eu não tinha uma versão duplicada do React, eu ainda estava recebendo o erro de gancho.

Mas tentar esta solução como mencionado acima corrigiu esse bug específico:

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

Então estou perdido.

Então estou perdido.

@orpheus Você renderiza mais de uma única raiz de reação na mesma página? aka você tem mais de uma chamada ReactDOM.render na mesma página?

Você renderiza mais de uma única raiz de reação na mesma página? aka você tem mais de uma chamada ReactDOM.render na mesma página?

@timkindberg

Eu não. Eu tenho meu ReactDOM.render na raiz do meu app , e o módulo lib que estou vinculando é uma biblioteca de componentes e não usa um ReactDOM.render em absoluto.

edit: estou fazendo algo parecido com:

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

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

onde <Root /> renderiza algo como

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

PermissionsProvider é o componente React que importo do meu módulo lib vinculado que usa um gancho que faz com que o aplicativo falhe. Ele cria estado e contexto e renderiza seus filhos.

Oi, estou usando elétron com ganchos de reação. se eu escrever meu próprio gancho, funciona. Mas gera erro quando uso ganchos de outro pacote em node_module, como react-use , swr .

Eu tenho que copiar o pacote para o meu arquivo local.

Alguém atende esse problema?

Exemplo de projeto aqui:
https://github.com/Zaynex/electron-react-ts-kit/tree/hooks-error

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

Eu também ainda estou tendo esse problema, mesmo depois de remover cópias duplicadas de react e react-dom. Criei um projeto de teste super simples para reproduzir.

$ 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

Atualmente, estou usando o método de alias do webpack, mas também tentei o método npm link e nenhum funcionou.

Também me deparei com esta questão. Estou usando ExpressJS + Pug para renderizar visualizações, então escrevi um renderizador (semelhante ao ReactRails) que permite renderizar componentes do lado do servidor e do cliente.

Tentei extrair isso para um pacote separado, pois estava ficando confuso e me deparei com esse problema.

Para corrigi-lo, tive que adicionar na chave resolve :

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

Agora funciona como esperado ao executar o webpack normalmente, mas o problema ainda persiste com um volume docker. Eu sou muito novo no docker para lidar com isso, então vou revisitá-lo mais tarde.

Edit: falei cedo demais. Funciona bem agora com React render, mas não com hydr.

Oi, estou usando elétron com ganchos de reação. se eu escrever meu próprio gancho, funciona. Mas gera erro quando uso ganchos de outro pacote em node_module, como react-use , swr .

Eu tenho que copiar o pacote para o meu arquivo local.

Alguém atende esse problema?

Exemplo de projeto aqui:
https://github.com/Zaynex/electron-react-ts-kit/tree/hooks-error

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

Olá. Eu tive o mesmo problema. Estou usando o electron-webpack que marca todos os módulos como externos para o webpack. Com poucas exceções codificadas - como react e react-dom.
Para mim, isso significava que o react carregado do meu código era diferente do react carregado desse módulo.
Adicionar esses módulos à lista de permissões parece ajudar (não tenho certeza se ainda não quebrou mais nada :)

@huhle obrigado, funciona! Talvez devêssemos mergulhar no elétron-webpack.

Acabei de conseguir fazer isso funcionar sozinho. Eu acho que é uma das melhores soluções quando se trata de espaços de trabalho Lerna e Yarn, e talvez algumas das peças possam ser usadas para outra solução.

Tudo parece se resumir à configuração do projeto package.json que estou importando. Eu precisava incluir estas seções:

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

Depois de fazer isso, tive que reconstruir os projetos e estava em funcionamento. Parece que listá-los como dependências de pares permite que eles sejam instalados pelo seu projeto consumidor. E como eles não estão listados nas dependências, eles não devem estar disponíveis para o pacote que você está tentando importar, mas por algum motivo, a menos que você diga para não subir, eles permanecem disponíveis e uma nova instância react entra e causa o erro.

Boa sorte!

Estou tentando usar react-spring para obter um efeito fade-in simples. Nada parece estar funcionando.
`import React, { useState, useEffect } de 'react';
import { animado, useTransition } from 'react-spring';

const TextContent = (props) => {

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 TextContent padrão;`
Capture

Tentei verificar se tenho várias instâncias do React. Npm ls-ing me diz que eu tenho apenas uma única versão de react e react-dom, ambos em 16.13.1.

Oi, estou usando elétron com ganchos de reação. se eu escrever meu próprio gancho, funciona. Mas gera erro quando uso ganchos de outro pacote em node_module, como react-use , swr .
Eu tenho que copiar o pacote para o meu arquivo local.
Alguém atende esse problema?
Exemplo de projeto aqui:
https://github.com/Zaynex/electron-react-ts-kit/tree/hooks-error
código principal:
https://github.com/Zaynex/electron-react-ts-kit/blob/hooks-error/src/renderer/app.tsx

Olá. Eu tive o mesmo problema. Estou usando o electron-webpack que marca todos os módulos como externos para o webpack. Com poucas exceções codificadas - como react e react-dom.
Para mim, isso significava que o react carregado do meu código era diferente do react carregado desse módulo.
Adicionar esses módulos à lista de permissões parece ajudar (não tenho certeza se ainda não quebrou mais nada :)

Brilhante! Obrigado

Estou tentando usar react-spring para obter um efeito fade-in simples. Nada parece estar funcionando.
`import React, { useState, useEffect } de 'react';
import { animado, useTransition } from 'react-spring';

const TextContent = (props) => {

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 TextContent padrão;`
Capture

Tentei verificar se tenho várias instâncias do React. Npm ls-ing me diz que eu tenho apenas uma única versão de react e react-dom, ambos em 16.13.1.

Mesmo aqui. react e react-dom estão em 16.13.1 para mim, e tentar usar react-spring traz esse mesmo erro.

De outro tópico em styled-components , aprendi que se você estiver usando um pacote local próprio por meio de um file: URI em package.json , você precisa rm -rf node_modules/local-package-name/node_modules antes de executar seu aplicativo, porque aparentemente, os pacotes locais são copiados sem verificar node_modules para dependências redundantes.

De outro tópico em styled-components , aprendi que se você estiver usando um pacote local próprio por meio de um file: URI em package.json , você precisa rm -rf node_modules/local-package-name/node_modules antes de executar seu aplicativo, porque aparentemente, os pacotes locais são copiados sem verificar node_modules para dependências redundantes.

Sim, esse é o mesmo problema para cerca de uma dúzia de casos de uso apenas neste tópico. Eu adicionei um alvo "prestart" e "prebuild" para fazer o rm -rf (usando rimraf). Outro usuário neste encadeamento usou npm-link-shared em seu pré-início para fazer com que os módulos compartilhassem a mesma instância de reação. Muitos de nós, usuários de monorepo, estão se deparando com isso.

Oi, estou usando elétron com ganchos de reação. se eu escrever meu próprio gancho, funciona. Mas gera erro quando uso ganchos de outro pacote em node_module, como react-use , swr .
Eu tenho que copiar o pacote para o meu arquivo local.
Alguém atende esse problema?
Exemplo de projeto aqui:
https://github.com/Zaynex/electron-react-ts-kit/tree/hooks-error
código principal:
https://github.com/Zaynex/electron-react-ts-kit/blob/hooks-error/src/renderer/app.tsx

Olá. Eu tive o mesmo problema. Estou usando o electron-webpack que marca todos os módulos como externos para o webpack. Com poucas exceções codificadas - como react e react-dom.
Para mim, isso significava que o react carregado do meu código era diferente do react carregado desse módulo.
Adicionar esses módulos à lista de permissões parece ajudar (não tenho certeza se ainda não quebrou mais nada :)

Isso também se aplica a pessoas com problemas com redux ou redux toolkit e electron-webpack. Eu tenho a seguinte configuração de trabalho:

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

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

Meu problema foi que eu escrevi

import React from 'React'

Ao invés de:

import React from 'react'

Às vezes são as coisas idiotas.

Eu resolvi isso adicionando o seguinte à minha configuração do webpack:

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

Inicialmente pensei que era um problema com o link npm, fiz tudo o que foi sugerido e até mudei para o yarn. Eventualmente, percebi que outra coisa estava acontecendo ao publicar no npm deu o mesmo erro ao importar em outro projeto.

Alguém aqui resolveu isso recentemente com um lerna monorepo? Eu tentei algumas das sugestões sem sorte.

Correndo para o erro depois de adicionar o código que é comentado com o // abaixo. Adicionar o CssBaseline e reagir as informações do fragmento causa o erro. Tudo corre bem quando é comentado. O código original é simplesmente o código básico do npx create-react-app. Completamente novo para isso e algumas das correções que tentei acima não tiveram efeito.

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

exportar função padrão App() {
Retorna (

        //<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 testes locais:
Na biblioteca node_modules exclua a pasta react e react-dom
No pacote principal, execute "yarn install" ou "npm install" novamente.

Isso evita que a segunda cópia do react seja carregada no bundle principal. Obviamente, não é uma correção permanente, mas funciona para testes locais.

Para quem usa lerna, você pode se deparar com este problema ao executar testes em um pacote, onde o código faz referência a componentes em outro pacote.

O problema que tivemos neste caso foi devido ao react sendo importado na especificação, e também sendo importado em um componente na árvore de componentes que estava usando o Material UI's withStyles , que é implementado usando ganchos no Material UI.

Parece que o react gerencia internamente o estado em uma variável ReactCurrentDispatcher.current , e isso acaba sendo definido em uma instância de react, mas usado em outra instância de react - quando está vazio, lança o Invalid hook call ... mensagem.

Já estávamos usando o Craco para substituir a configuração do webpack do Create React App em tempo de compilação:

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

No entanto, essa substituição do webpack é usada apenas em tempo de compilação -- ao executar os testes, o código não é compilado, mas instanciado da fonte -- então nossa solução foi usar CracoAlias ​​em nosso craco.config.js para especificar o caminho de reação durante os testes:

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

Usei @craco/craco como solução, sem ejetar, seguindo o exemplo de @apieceofbart . As etapas para mim foram as seguintes usando npm link para testar o módulo local:

  1. Instale o craco no meu aplicativo de demonstração executando npm i @craco/craco --save
  2. Crie o arquivo de configuração craco.config.js para fazer o root onde o package.json reside no aplicativo de demonstração.
  3. Altere os scripts start , build e test substituindo react-scripts por craco no meu aplicativo de demonstração.
// craco.config.js
const path = require('path');

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

edit: nem percebi que @jasondarwin teve a mesma ideia.

Passei o melhor de um dia tentando corrigir esse problema. Postando minha solução aqui caso ajude alguém.

Estamos usando um monorepo e dois pacotes estavam importando instâncias diferentes do react, mas estavam resolvendo no mesmo local nos módulos do nó raiz. Acontece que tivemos essas duas instâncias porque um dos aplicativos estava usando seu próprio webpack para criar um pacote. Isso estava sendo içado corretamente para o módulo do nó raiz, mas obteria sua própria instância quando importado por esse pacote. A solução foi incluir react e react DOM nas externas da configuração do webpack para que o webpack não criasse uma nova instância de react para o pacote.

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

Espero que isso ajude alguém!

Para mim, estava usando o react-hot-loader versão 4.0.0, atualizar para react-hot-loader 4.8 parece fazer o truque

Estou recebendo a mensagem Invalid hook call SOMENTE ao executar meus testes em um Hook personalizado que estou criando para trabalhar com janelas Modal.

Para demonstrar o comportamento, criei um exemplo no seguinte:
(https://github.com/BradCandell/invalid-hook-example)

  • Apenas uma versão de react e react-dom

Estou perdendo algo terrivelmente óbvio? Quando eu quebrei a regra no passado, o npm start falharia. Mas isso só está falhando nos meus testes.

Agradeço a ajuda!
-Brad

Eu resolvi isso adicionando o seguinte à minha configuração do webpack:

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

Inicialmente pensei que era um problema com o link npm, fiz tudo o que foi sugerido e até mudei para o yarn. Eventualmente, percebi que outra coisa estava acontecendo ao publicar no npm deu o mesmo erro ao importar em outro projeto.

Isso resolveu para mim. Eu estava importando react-toastify e estava recebendo a chamada de gancho inválida. Eu passei por cada item no erro do console:

  1. Você pode ter versões incompatíveis de React e React DOM.

    1. Você pode estar quebrando as Regras dos Ganchos.

    2. Você pode ter mais de uma cópia do React no mesmo aplicativo.

Acabou sendo a 3ª edição. Eu segui isso:
https://reactjs.org/warnings/invalid-hook-call-warning.html#duplicate -react

Nenhuma das soluções acima funcionou para mim, até que percebi que estava agrupando outra cópia do react com a biblioteca que estava _importando_.
Eu tinha transpilado e empacotado o código-fonte da minha biblioteca, então a verificação de diferentes versões do React listadas nos documentos estava retornando true em vez de false .
Marcar react como uma dependência externa e deixá-la fora do pacote da minha biblioteca resolveu o problema.

Meu caso não era um monorepo, mas uma situação um pouco semelhante. Estamos desenvolvendo uma nova estrutura de interface do usuário e, em vez de usar npm link ou lerna, usamos apenas aliases do webpack para exigir os arquivos em uma pasta irmã. Funciona bem, mas você vai se deparar com esse problema. Felizmente, a solução de @apieceofbart corrigiu o problema para nós.

Linha 130:21: React Hook "useStyles" é chamado na função "pharmacyDashboard" que não é um componente de função React ou uma função React Hook personalizada react-hooks/rules-of-hooks
Linha 133:45: React Hook "React.useState" é chamado na função "pharmacyDashboard" que não é um componente de função React ou uma função React Hook personalizada react-hooks/rules-of-hooks

este é o erro.....alguém pode me ajudar a resolver isso

@vyshnaviryali é melhor você chamar sua função usePharmacyDashboard

./src/components/HomeFiles/AppFooter.js
Linha 1:1: a definição da regra 'material-ui/no-hardcoded-labels'' não foi encontrada material-ui/no-hardcoded-labels'
alguém pode me ajudar a resolver isso

Para todos que estão executando este problema com npm link porque você precisa adicionar recursos aos seus componentes, mas não deseja npm publish antes de testar, estou surpreso que ninguém sugeriu usar yalc (https://www.npmjs.com/package/yalc)

Para todos que estão executando este problema com npm link porque você precisa adicionar recursos aos seus componentes, mas não deseja npm publish antes de testar, estou surpreso que ninguém sugeriu usar yalc (https://www.npmjs.com/package/yalc)

Na verdade, eu fiz ano passado: https://github.com/facebook/react/issues/13991#issuecomment -535150839

Estamos usando há quase um ano sem problemas.

Outro aqui usando lerna; para corrigir isso, movi as dependências react e react-dom para minha raiz package.json .

Eu tive o mesmo problema e resolvi adicionando:

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

para a propriedade resolve na configuração do webpack do meu aplicativo principal.

Obviamente foi um erro meu usar duas cópias do React, mas concordo que seria ótimo se a mensagem de erro fosse melhor. Acho que talvez seja semelhante a: #2402

Para aqueles que estão usando o método acima, mas ainda recebem os erros ao executar o jest, adicione-os a moduleNameMapper na configuração do jest (omita react-dom se não for necessário):

moduleNameMapper: {

...

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

...

}

Estou perdido. Estou recebendo isso, mas meu aplicativo não usa nenhum gancho e não há duplicatas de react ou react-dom. Estou usando next.js. Isso pode ter algo a ver?

npm ls react
npm ls react-dom

@maapteh foi isso para mim? Eu executei esses comandos e não encontrei duplicatas. Ambas as bibliotecas estão na versão 16.13.1

@dancancro Também estou usando o Next.js e não consigo corrigir isso.

npm ls react e npm ls react-dom retornam apenas uma entrada. Mas não tenho certeza se está correto. Eu me deparo com este erro ao vincular a um pacote local para desenvolvimento. npm ls retorna apenas uma entrada mesmo quando eu não vinculo react na dependência de volta ao repositório principal. Mas mesmo quando o link reajo corretamente, ainda recebo o erro.

@justincy Não tenho nenhum link de pacote no meu projeto. Aposto que está relacionado ao Next.js. O problema desaparece se eu colocar o componente principal dentro de um typeof document !== 'undefined' , prejudicando efetivamente o propósito do Next.js

Consegui corrigir meu problema excluindo react e react-dom de node_modules na dependência. Não é o ideal, mas pelo menos posso continuar trabalhando.

@dancancro Estou cético de que seu problema seja causado pelo Next.js. Se fosse, muitas outras pessoas teriam o problema. Eu só estou correndo para ele por causa de pacotes vinculados. Não vejo o erro sem pacotes vinculados.

O problema desaparece se eu remover cinco dos sete componentes do componente principal. Não consigo ver nada de especial nesses componentes. Envolver esses componentes em typeof document !== 'undefined' s também funciona.

Oi equipe, estou tentando atualizar a versão do React de 16.2.0 para 16.13.1, também fiz o mesmo para react-dom.
Agora eu tenho um componente wrapper que está sendo chamado em "/test"

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

no wrapper de teste eu importei um componente funcional com um gancho
function TestComponent(props) { useEffect(() => { console.log("TEST COMPONENT"); }); return ( <div> Hello world! </div> ) }

Mas quando a página renderiza o gancho UseEffect não funciona e ocorre um erro, ou seja, Aviso de chamada de gancho inválida
PS. :

  1. Eu verifiquei que tenho apenas uma cópia do react e o react-dom está instalado
  2. A versão React e react-dom é 16.13.1

Isso é o que eu tenho
Eu só ...
@ @
ReactError
Eu uso nextJS para que não precise de importação do React. E eu tentei - não ajuda.

Todas as outras páginas e funções estão funcionando perfeitamente

@Brotipok qual versão do next.js? (Vendo problemas semelhantes, mas apenas ao passar para 9.5 de 9.4.X)

Oi!

Estou com o mesmo erro, apenas um pacote para react e react dom quando faço npm ls.

Versão do React: 16.13.1
Versão do React-dom: 16.13.1

Estou usando typescript e inicializei o projeto com create-react-app my-app --template typescript.

O componente funcional só está funcionando se eu não estiver usando ganchos dentro dele.

Package.json

{
"name": "blablamovie",
"versão": "0.1.0",
"privado": verdadeiro,
"dependências": {
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.5.0",
"@testing-library/user-event": "^7.2.1",
"@types/jest": "^24.9.1",
"@types/node": "^12.12.53",
"@types/react": "^16.9.43",
"@types/react-dom": "^16.9.8",
"@types/react-router-dom": "^5.1.5",
"react-icons": "^3.10.0",
"react-scripts": "3.4.1",
"datilografado": "^3.7.5",
"webpack-bundle-analyzer": "^3.8.0"
},
"roteiros": {
"start": "react-scripts start",
"build": "construir scripts de reação",
"teste": "teste de scripts de reação",
"eject": "react-scripts eject",
"analyze": "source-map-explorer 'build/static/js/*.js'"
},
"eslintConfig": {
"extends": "react-app"
},
"lista de navegadores": {
"Produção": [
">0,2%",
"não está morto",
"não op_mini tudo"
],
"desenvolvimento": [
"última 1 versão cromada",
"última 1 versão do Firefox",
"última versão 1 safári"
]
}
}
É um projeto importante e está me deixando um pouco louco.
Se alguém puder ajudar seria ótimo.
Obrigado.

@Brotipok qual versão do next.js? (Vendo problemas semelhantes, mas apenas ao passar para 9.5 de 9.4.X)

Aqui estão as dependências
"dependências": {
"próximo": "9.4.4",
"próximas imagens": "^1.4.0",
"node-sass": "^4.14.1",
"reagir": "16.13.1",
"react-document-meta": "^3.0.0-beta.2",
"react-dom": "16.13.1",
"react-horizontal-timeline": "^1.5.3",
"react-meta-tags": "^0.7.4",
"react-onclickoutside": "^6.9.0"
},
"devDependencies": {
"@types/node": "^14.0.23",
"@types/react": "^16.9.43",
"datilografado": "^3.9.7"
}

Estou enfrentando o mesmo problema ao importar componentes material-ui/core/Dialog , configurei meu package.json para usar react 16.8.0 especificamente para react e react-dom importações.

Eu executei npm ls react e npm ls react-dom com apenas uma importação Eu também tentei o teste descrito na página de erro:

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

Que retorna false , porém como eu rastrearia a versão "diferente" do react que está sendo importada por uma dependência?, parece que só acontece quando importo o componente Material UI Dialog , acontece assim que tocar um botão que o aciona para renderização. Consigo usar outros componentes como List e ListItems , etc.

Tentei forçar resoluções e também não resolveu.

Eu não estou usando o web pack (projeto realmente pequeno), então a compilação acontece com react-scripts build se isso fizer diferença.

Reescrever: vou apenas substituir minha pergunta por uma referência de solução (e talvez um pedido de ainda mais clareza de termos nos documentos, para nós, manequins? :))

Fundo:
Eu estava tentando compilar com o webpack um componente funcional com ganchos em um ativo onde esse componente poderia ser chamado do vanilla JS no navegador.

Por exemplo,

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

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

...que eu queria que fosse exportado como um módulo em si, e depois de carregar esse ativo, use-o diretamente do HTML, semelhante a:

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

Eu tenho isso funcionando há muito tempo _desde que o componente não contenha ganchos_. Mas ao usar ganchos, continuei me deparando com essa temida mensagem de erro.

A solução simples de virar a mesa
Eu segui _muito_ de pistas falsas mais complicadas (várias versões/instâncias de react/reactDOM, importações npm e dependências secundárias ocultas, react-hot-loader, configuração de webpack, externals, diferentes convenções de pacote/módulo/biblioteca, estrutura pós-compilação .. .) antes de tentar isso, que funcionou:

export default () => <Example />;

(ou export default props => <Example {...props} /> quando aplicável).

Na retrospectiva 20/20, faz sentido, eu acho.

Mas apenas para identificar a fonte de confusão no caso de alguém precisar disso: os documentos de regras de ganchos dizem _Chame-os no nível superior no corpo de um componente de função_. O que eu pensei que fiz, já que na verdade colei o exemplo diretamente na minha estrutura.

Minha interpretação é que isso , a partir dos exemplos...

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

... NÃO é um componente de função em si? Torna-se assim no contexto de chamada correto (então, não Example() mas <Example /> ).

Acho que posso ter perdido em outro lugar nos documentos, mas caso não: teria me economizado muito tempo se um pouco de contexto de uso (ou apenas uma configuração de módulo ES) fosse incluído/mencionado/vinculado. :) Especialmente porque a versão direta export default Example funciona sem ganchos.

Obrigado por uma solução de trabalho @apieceofbart! Meu problema estava relacionado ao link npm.

Veja como eu consegui trabalhar com o Create React App, onde a configuração do Webpack está oculta por design. Pode ser a sua solução também @florianzemma?

  1. npm install -D react-app-rewired
  2. Crie um arquivo chamado config-overrides.js na raiz do seu projeto.
// 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. Substitua react-scripts ... -commands relevantes em package.json por react-app-rewired ... .

Espero que ajude

Eu recebi esse erro porque carreguei os pacotes 2 vezes.
No meu caso, aconteceu porque o modelo nunjucks onde as tags de script foram renderizadas foi usado 2 vezes - no próprio layout e no modelo geral para o conteúdo da tag head,

Solução alternativa do fio

Estou usando o Yarn e consertei isso forçando a resolução no meu package.json :

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

Além de adicionar a resolução no aplicativo pai (biblioteca consumidora), atualizei as dependências da biblioteca com os seguintes comandos:

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

Depois disso, vinculei novamente a biblioteca no aplicativo pai com yarn add link:/path/to/library

Oi
Estou me deparando com o mesmo problema com os espaços de trabalho do fio.
Eu tenho um layout assim:

área de trabalho/
├── biblioteca/
├── aplicativo1/
├── aplicativo2/

app1 e app2 têm dependências diretas para react v16.9.0, react-dom v16.9.0 e 'library'.
'library' tem uma dependência de pares para reagir v16.9.0, mas também uma dependência dev no storybook.
O problema parece vir do livro de histórias que tem uma dependência do react v16.13.1.
No entanto, quando executo o yarn install, acabo com react 16.13.1 nos meus node_modules de nível superior e react 16.9.0 nos node_modules locais de app1 e app2.

Quando executo o app1 (criado com CRA), ele está usando o react v16.9.0 local, mas os componentes da 'library' estão usando o React v16.13.1

Isso me parece ser um problema com a lógica de içamento de fios, a definição de webpack do create-react-apps ou ambos?
Alguém tem alguma ideia de solução para esse cenário?

Oi
Estou me deparando com o mesmo problema com os espaços de trabalho do fio.
Eu tenho um layout assim:

área de trabalho/
├── biblioteca/
├── aplicativo1/
├── aplicativo2/

app1 e app2 têm dependências diretas para react v16.9.0, react-dom v16.9.0 e 'library'.
'library' tem uma dependência de pares para reagir v16.9.0, mas também uma dependência dev no storybook.
O problema parece vir do livro de histórias que tem uma dependência do react v16.13.1.
No entanto, quando executo o yarn install, acabo com react 16.13.1 nos meus node_modules de nível superior e react 16.9.0 nos node_modules locais de app1 e app2.

Quando executo o app1 (criado com CRA), ele está usando o react v16.9.0 local, mas os componentes da 'library' estão usando o React v16.13.1

Isso me parece ser um problema com a lógica de içamento de fios, a definição de webpack do create-react-apps ou ambos?
Alguém tem alguma ideia de solução para esse cenário?

A única solução que encontrei para isso foi yarn run eject o aplicativo CRA e mudar a ordem da seção resolve de:

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

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

Parece estranho para mim que o 'appNodeModules' não seja a prioridade mais alta - certamente o aplicativo real em questão deve ser adiado quando se trata de resolver dependências?

Eu encontrei o problema de 'ganchos' em uma configuração envolvendo Webpack e Electron. Meu projeto tem uma dependência de um módulo A que é empacotado pelo Webpack (e que eu mesmo criei). Eu externalizei o React de A (declarando que é um módulo commonjs2). Isso exclui os arquivos React do pacote da biblioteca.

Meu programa principal, rodando no processo Electron Renderer, também usa React. Eu fiz o Webpack incluir o React no pacote (sem configuração especial).

No entanto, isso produziu o problema dos 'ganchos' devido a duas instâncias do React no ambiente de tempo de execução.

Isso é causado por estes fatos:

  • módulo A 'requer' React e isso é resolvido pelo sistema de módulos do Electron. Então o Electron pega o React de node_modules;
  • o programa principal depende do tempo de execução do Webpack para 'carregar' o React do próprio pacote.
  • tanto o Electron quanto o tempo de execução do Webpack têm seu próprio cache de módulo ...

Minha solução foi externalizar o React do programa principal também. Dessa forma, tanto o programa principal quanto o módulo A obtêm seu React do Electron - uma única instância na memória.

Eu tentei qualquer número de aliases, mas isso não resolve o problema, pois um alias apenas instrui o Webpack onde encontrar o código do módulo. Não faz nada em relação ao problema de caches de vários módulos!

Se você se deparar com este problema com um módulo que não pode controlar, descubra se e como o React é externalizado. Se não for externalizado, acho que não dá para resolver esse problema no contexto do Electron. Se for apenas externalizado como global, coloque o React em seu arquivo .html e faça com que seu programa principal dependa disso também.

Finalmente...

//webpack.config.js

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

Vue3 tem o mesmo problema

Resolvi esse problema colocando react e react-dom como peerDependencies no meu package.json da minha biblioteca externa, que usa React.

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

Acho que posso ter perdido em outro lugar nos documentos, mas caso não: teria me economizado muito tempo se um pouco de contexto de uso (ou apenas uma configuração de módulo ES) fosse incluído/mencionado/vinculado. :) Especialmente porque a versão direta export default Example funciona sem ganchos.

Olá @espen42 ,
Eu realmente esperava que sua solução nos ajudasse. Nós literalmente tentamos _tudo_, assim como você mencionou.

Infelizmente, sua solução também não parece ajudar. Eu me pergunto, talvez eu tenha perdido alguma coisa?

Então, em um pacote (vou chamá-lo de @bla/bla), temos o index.js que possui um componente com ganchos, como

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

Nós compilamos o pacote usando npx babel .

Vinculamos este pacote com npm link e o incluímos no projeto como npm link @bla/bla .
Tanto o pacote quanto o projeto usam a mesma versão do React e react-dom.

No projeto, incluímos o pacote assim:

import Bla from `@bla/bla`

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

export default RenderBla

Infelizmente, o erro ainda persiste.
Invalid hook call. Hooks can only be called inside of the body of a function component.

O que podemos estar perdendo?

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

Este resolveu o problema para mim, muito obrigado cara ❤️

Erro do Field Customizer quando acessado via link externo (Sharepoint Online)

Uma extensão do personalizador de campo spfx com alguns componentes de interface do usuário de malha, quando acessado via link, obtendo um desses erros dependendo da versão do fabricUI:
https://reactjs.org/docs/error-decoder.html/?invariant=321 ,
https://reactjs.org/docs/error-decoder.html/?invariant=290&args []=A.%20Geral

quando a página é atualizada, tudo funciona corretamente.
Eu não usei nenhum React Hooks no código, apenas React Components.
Também não usei refs.

Eu acho que pode ser por causa da interface do usuário do Fabric, quando todos os componentes da interface do usuário do tecido são removidos, nenhum erro ocorre.

Tentei diferentes versões do fabic ui, 6.189.2, 6.214.0 e 7.114.1 e também tentei substituir todas as referências fabric-ui por ui fluente, o problema ainda persiste

verifiquei as versões de reação, aqui está a saída
npm ls reage
+-- @microsoft/sp- webpart [email protected]
| +-- @microsoft/ [email protected]
| | -- [email protected] deduped | +-- @microsoft/[email protected] | | -- [email protected] desduplicado
| +-- @microsoft/sp-property-pane@ 1.9.1
| | -- [email protected] deduped | -- [email protected] desduplicado
`-- [email protected]

Olá a todos,
Eu também tropecei neste erro irritante. No meu caso, isso também foi uma configuração incorreta da minha compilação do webpack no final. Mas nenhuma das coisas sugeridas nesta edição funcionou para mim. Então quero compartilhar minha experiência também.

Minha página inclui vários pontos de entrada e o SplitChunkPlugin pode criar blocos de tempo de execução. Como estamos usando a gem rails-webpacker, ela foi configurada por padrão para criar um tempo de execução para cada pedaço. Mas o webpack faz algo semelhante por padrão, inclui o tempo de execução dentro dos pedaços.

Claro que a documentação avisa sobre este caso, mas você tem que encontrá-lo. Definir optimization.runtimeChunk para single criará um tempo de execução separado. Isso impedirá sua compilação de instanciar várias cópias de react, ao usar react de vários pontos de entrada.

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

Oi a todos,
Estou com o problema de querer usar uma lib externa que vem de um CDN e vem com uma tag <script> , então não há muito que eu possa fazer com o código em si. A lib usa react e hooks, então eu recebo o
3. You might have more than one copy of React in the same app erro.
Infelizmente, não há pacote NPM para a biblioteca: https://github.com/Anyline/anyline-ocr-anylinejs-module
Estou usando o CRA e o projeto não é ejetado.

Criei um pequeno exemplo Sandbox .

Ele lança o mesmo erro, pois o outro pacote também está usando ganchos, mas com seu próprio React. Eu tive que publicar meu pacote no NPM e depois importá-lo diretamente do NPM. que

Eu entro nesta questão recentemente e me pergunto por quê.
Eu resolvi isso fazendo o upload para o GitLab e instalá-lo por endereço.
Qual é a diferença entre pacote e pacote local?

Descobri que recebo a "chamada de gancho inválida". quando eu carrego dinamicamente o Component que está chamando o gancho.

Caixa de areia de código

O teste que carrega "App" passa estaticamente. Os dois testes que o carregam dinamicamente (um usando require , outro usando import como função) ambos dão o erro.

Por que eu me importo: estou tentando escrever alguns testes onde estou usando jest.doMock para simular algumas coisas e depois carregar dinamicamente o módulo que quero testar, conforme a documentação . Estou usando doMock em vez de Mock porque preciso ser capaz de zombar de coisas de maneira diferente em funções diferentes. Você notará que o erro ocorre sem qualquer simulação envolvida.

Ele lança o mesmo erro, pois o outro pacote também está usando ganchos, mas com seu próprio React. Eu tive que publicar meu pacote no NPM e depois importá-lo diretamente do NPM. que

Eu entro nesta questão recentemente e me pergunto por quê.
Eu resolvi isso fazendo o upload para o GitLab e instalá-lo por endereço.
Qual é a diferença entre pacote e pacote local?

@catsheue foi React1 === React2 true para você?
eu não tive o meu publicado no npm ainda queria saber se essa é a causa

o meu parece ser React1 === React2 = true e não encontrei uma solução por que isso está acontecendo ao importar minha biblioteca de reação para um projeto

Tive esse mesmo problema usando yarn link para testar uma biblioteca local. Meu erro foi listar react e react-dom como dependências de desenvolvimento e não pares.

Então eu deveria ter feito yarn add --peer react react-dom . Finalmente, como eu já cometi o erro de confirmar o React como uma dependência dev, precisei limpar node_modules da minha biblioteca. rm -rf node_modules; yarn resolveu o problema para mim.

Eu também enfrentei esse problema. No meu caso, foi causado por um React duplicado do Storybook (v6.0.28). Acredito que você pode encontrar mais informações aqui .

Eu desinstalei as dependências do Storybook, deletei node_modules e executei yarn install novamente. Isso funcionou para mim. Espero que ajude alguém a evitar as lágrimas e as horas perdidas com isso.

Esta solução alternativa funciona para mim também. Estou usando o Firebase Functions e tenho uma pasta node_modules na raiz do meu projeto e no diretório /functions/ . Se eu excluir /functions/node_modules , meu aplicativo funcionará bem. Esta é uma solução alternativa, mas é bastante irritante. Alguém encontrou uma solução alternativa que permite que as duas pastas node_modules existam ao mesmo tempo?

Para a posteridade e qualquer pessoa que possa estar enfrentando esse problema ao usar mdbootstrap em um aplicativo criado com create-react-app .

Eu vi esse erro ao adicionar vários componentes mdbootstrap, como botões e imagens de cartão. A saída do console adicionada ao index.js para solução de problemas conforme o artigo de suporte do React retornou true na comparação de versões. Então eu tive que tentar outra coisa.

A correção foi executar um npm dedupe

npm ls react

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

npm dedupe

npm ls react

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

Depois disso, todos os componentes funcionaram bem. Dias felizes.

Descobri que recebo a "chamada de gancho inválida". quando eu carrego dinamicamente o Component que está chamando o gancho.

Caixa de areia de código

O teste que carrega "App" passa estaticamente. Os dois testes que o carregam dinamicamente (um usando require , outro usando import como função) ambos dão o erro.

Por que eu me importo: estou tentando escrever alguns testes onde estou usando jest.doMock para simular algumas coisas e depois carregar dinamicamente o módulo que quero testar, conforme a documentação . Estou usando doMock em vez de Mock porque preciso ser capaz de zombar de coisas de maneira diferente em funções diferentes. Você notará que o erro ocorre sem qualquer simulação envolvida.

@miket01 Exatamente o que tento fazer (mas sem zombar). Você encontrou alguma solução?

Encontrou isso fazendo:

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

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

Corrigido chamando useState primeiro:

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

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

Ainda estou recebendo esse erro depois de deixá-lo de lado por muitos meses.

Eu uso zero ganchos no meu programa. Há exatamente uma cópia de react e uma cópia de react-dom e são a mesma versão. Não há links.

Ele funcionou parcialmente antes de eu tentar atualizar alguns pacotes para corrigir problemas de segurança. Estou usando next.js e a correção foi excluir alguns subcomponentes do componente de nível superior envolvendo-os em {typeof window !== 'undefined' mas agora isso também não 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

O erro é lançado porque ReactCurrentDispatcher.current === null mas não consigo encontrar em nenhum lugar no /node_modules/react/cjs/react.development.js onde isso está definido para algo.

Alguém pode me dizer onde ReactCurrentDispatcher.current deveria estar recebendo um valor?
https://github.com/facebook/react/search?p=2&q=%22ReactCurrentDispatcher.current+%3D%22&type=code

Isso parece um candidato, mas esse código não está contido no meu react-development.js . Deveria 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

Estou recebendo este erro com renderização do lado do servidor por next.js e esse código está na fonte de reação em react-dom/server . Como posso determinar se /node_modules/react/cjs/react-development.js está correto?

ATUALIZAÇÃO: Este era o problema. Eu editei webpack.config.externals no meu arquivo next.config.js
https://github.com/vercel/next.js/issues/17592#issuecomment -712443172

Meu aplicativo gera um erro enorme (chamada de gancho inválida) sempre que tento integrar a interface do usuário do material nele. Eu sou completamente novo no React, então preciso de ajuda.

Esta página foi útil?
0 / 5 - 0 avaliações