React: Hooks + React의 여러 인스턴스

에 만든 2018년 10월 27일  ·  285코멘트  ·  출처: facebook/react

검색에서 오는 사람들에게: 먼저 이 페이지를 읽으십시오 . 여기에는 가장 일반적인 가능한 수정 사항이 포함되어 있습니다!

기능 을 요청하거나 버그 를 보고하시겠습니까?

상승

현재 행동은 무엇입니까?

실수로 React의 여러 인스턴스가 있었습니다.

후크를 사용하려고 할 때 다음 오류가 발생했습니다.
hooks can only be called inside the body of a function component

함수 구성 요소를 사용하고 있었기 때문에 올바르지 않습니다. 문제의 진정한 원인을 찾는 데 시간이 걸렸습니다.

예상되는 동작은 무엇입니까?

올바른 오류 메시지를 표시합니다. 앱에 React의 여러 인스턴스가 있음을 감지하고 이것이 버그의 원인일 수 있다고 말할 수 있습니다.

Hooks Discussion

가장 유용한 댓글

나는 같은 문제가 있었고 다음을 추가하여 해결했습니다.

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

내 메인 앱의 webpack 구성에서 resolve 속성으로 변경합니다.

두 개의 React 사본을 사용한 것은 분명히 내 실수였지만 오류 메시지가 더 좋았더라면 좋았을 것이라는 데 동의합니다. 나는 이것이 아마도 https://github.com/facebook/react/issues/2402 와 비슷하다고 생각합니다.

모든 285 댓글

설명을 위해: 구성 요소를 렌더링하는 데 사용된 것과 다른 react 모듈에서 후크(예 useState )를 가져오고 있었습니까?

나는 이것이 혼란스럽다는 것에 동의합니다. 다른 React 모듈이 렌더링 중인지 알 수 있는 방법이 있는지 확실하지 않습니다. AFAIK 우리는 여러 React 인스턴스가 문제 없이 동일한 전역 컨텍스트에서 작동할 수 있도록 최대한 격리된 React를 실행하려고 합니다.

그렇지 않으면 오류 메시지를 업데이트하고 너무 혼란스럽지 않은 경우 이 경우도 언급할 수 있습니다.

예, React1 === React2 를 비교했는데 false (React1은 index.js에서, React2는 후크를 사용하여 파일에서 가져옴). 이 경우 위의 일반 오류 메시지와 함께 후크가 실패합니다.

이 문제는 이 사례에 대한 인식을 높이고 이 문제에 직면한 사람들을 돕기 위해 오류 메시지를 개선하기 위한 것입니다. 그것은 아마도 매우 가장자리 일 것입니다.

예, 내가 만들고 있는 패키지를 npm 링크 하려고 했습니다. 다른 패키지도 후크를 사용하지만 자체 React를 사용하기 때문에 동일한 오류가 발생합니다. 내 패키지를 NPM에 게시한 다음 NPM에서 직접 가져와야 했습니다. 그런 식으로 오류가 사라졌지만 테스트하지 않고 패키지를 게시한 이후로 문제가 해결되기를 바랍니다.

Lerna monorepos는 사용자 정의 후크가 한 패키지에서 정의되고 심볼릭 링크된 종속성이 자체 반응 복사본을 사용하기 때문에 다른 패키지에서 사용하는 경우에도 이 문제를 겪습니다.

현재 npm-link-sharedprestart npm 스크립트를 사용하여 한 패키지의 react 종속성을 다른 패키지에 대한 심볼릭 링크로 대체하는 (해키) 해결 방법이 있으므로 사용합니다. 같은 사례.

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

나는 같은 문제가 있었고 다음을 추가하여 해결했습니다.

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

내 메인 앱의 webpack 구성에서 resolve 속성으로 변경합니다.

두 개의 React 사본을 사용한 것은 분명히 내 실수였지만 오류 메시지가 더 좋았더라면 좋았을 것이라는 데 동의합니다. 나는 이것이 아마도 https://github.com/facebook/react/issues/2402 와 비슷하다고 생각합니다.

@mpeyper 작동합니다. 감사 해요

@pieceofbart 그것은 나를 위해 일했습니다. 제안해 주셔서 감사합니다. 👍

동일한 번들에 여러 개의 React 사본이 있을 때 이 문제가 발생한다는 것을 이해합니다.

자체 React 사본이 있는 두 개의 개별 번들이 https://medium.jonasbandi.net/hosting-multiple-react-applications-on- 에 설명된 것처럼 별도의 dom 요소에서 자체 React 애플리케이션을 부트스트랩하는 경우에도 문제가 되나요?

후자는 단일 스파 메타 프레임워크(https://github.com/CanopyTax/single-spa)에서 예를 들어 사용되는 일반적인 "통합" 패턴이라고 생각합니다.

나는 또한 똑같은 반응 버전에서도 이 문제를 겪고 있습니다. npm-link 를 사용할 때 자체적으로 게시할 후크를 개발하는 것이 깨집니다. 도움이 되지 않는 동일한 hooks can only be called inside the body of a function component 메시지가 표시됩니다. @pieceofbart 의 별칭 솔루션이 나를 위해 이것을 해결했습니다. 정말 고마워!

내 기본 응용 프로그램에 패키지를 npm link 할 때도 동일한 문제가 발생합니다. babel-plugin-module-resolver 을(를) 사용할 수 없습니다.
그것은 말한다:
Could not find module './node_module/react'
내 구성 요소를 게시하기 전에 로컬에서 테스트할 수 없기 때문에 성가신 일입니다.

"react": "^16.7.0-alpha.2" 에서 캐럿 을 제거하여 문제를 해결했습니다.
다음은 전체 의견입니다. https://github.com/facebook/react/issues/14454#issuecomment -449585005

저는 Yarn을 사용하고 있으며 package.json 에서 강제로 해결 하여 이 문제를 해결했습니다.

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

여기도 마찬가지!!

나와 같은 방식으로 이 문제를 겪었을 수 있는 누군가를 위해 여기에 메모를 남기고 싶었습니다.

react-rails gem으로 React와 Rails를 실행하고 구성 요소를 Rails 보기에 직접 렌더링합니다. Turbolinks가 React의 추가 인스턴스를 로드한 <head> 에서 새 JS 번들을 가져왔기 때문에 앱의 새 버전이 푸시될 때마다 이 오류가 발생했습니다. 해결책은 번들이 변경된 것을 감지할 때 Turbolinks 가 전체 페이지를 다시 로드하도록 하는 것이었습니다.

이것은 우리를 위해 그것을 해결한 것으로 보입니다.

Hooks를 마침내 프로덕션에 도입하게 되어 매우 기쁩니다. 우리 모두는 Hooks를 가능하게 해준 모든 분들께 깊은 감사를 드립니다. 그것들은 작업하기에 _ _ 재미있고 내 코드 더 짧고 선언적으로 만들었습니다.

참고로 이 문제는 "후크는 함수 구성 요소의 본문 내에서만 호출할 수 있습니다."와 같은 도움이 되지 않는 동일한 오류 메시지와 함께 릴리스된 버전과 여전히 관련이 있습니다.

고칠 수 있는 일인가요? 더 많은 개발자가 새로운 기능을 구현하기 시작하고 더 명확한 오류 메시지가 완전한 "수정" 대신에 먼 길을 갈 것이기 때문에 이것이 점점 더 널리 퍼질 수 있다고 상상합니다.

다시 한 번 모든 노고에 감사드리며 출시를 축하드립니다! 정말 놀라운 기능 모음입니다.

편집 : 열린 PR을 더 자세히 살펴봤어야 했는데 이 문제를 해결하는 #14690을 찾았습니다. @threepointone 감사합니다!

@taylorham 커밋의 링크는 아직 아무 것도 가리키지 않습니다. 나는 그것을 기다릴 것이지만 이것은 연결된 _( npm link )_ 패키지에서 후크를 사용한 이후로 겪었던 문제이며 게시하지 않고 로컬로 작업하는 것은 불가능합니다.
여러 문제를 살펴본 후 이것이 구성 요소를 클래스로 컴파일하는 react-hot-loader의 문제 라고 확인했지만 Hook 지원 버전을 출시한 후에도 여전히 같은 방식으로 실패합니다.
나는 많은 다른 해킹을 시도했지만 운이 없었습니다. 왜 모든 사람들이 아직 이 문제에 대해 고민하지 않았는지 모르겠습니다 🧐

@dotlouis 예, 지금까지 업데이트된 오류 메시지일 뿐이며 문제 자체는 여전히 고통스럽습니다.

나를 위해 일한 유일한 것은 "react": "link:../my-library/node_modules/react" 를 사용하여 내가 개발 중인 앱이 라이브러리의 React 인스턴스에 의존하도록 만드는 것입니다.

  • 제안된 해결 방법 중 어느 것도 효과가 없었고 모든 방법을 시도했습니다.
  • 컨텍스트 및 많은 HOC를 구현하는 프로젝트에 설치하려고
  • 빈 프로젝트에서 시작하여 트릭을 수행했습니다.
  • 나는 계속해서 원인을 찾고 있다

[ok] 저에게 수정은 package.json 또는 다른 이중 반응 원인에 대한 것이 아닙니다. 컨텍스트에서 오는 내 앱 위에 글로벌 themeProvider가 있습니다. "useContext Hook"으로 교체하는 것(기능적 comp로 다시 작성하는 동안)이 유일한 해결책인 것 같았습니다.
아마도 문제가있을 때

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

create-react-app 를 사용하는 example 폴더가 있는 구성 요소를 개발 중입니다.

package.json 에서 이 문제를 해결했습니다.

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

@taylorham @DylanVann 의견 을 보내주셔서 감사합니다. 불행히도 아직까지는 작동하지 않습니다.
그리고 귀하가 사용한 이 link: 프로토콜에 대한 문서를 찾을 수 없습니다.
기본적으로 "react-spring"(리액트를 종속성으로 사용하는 또 다른 dep)은 react-dom 를 찾을 수 없다고 말합니다. "react": "link:../some/path" 에 대한 문서를 알려 주시겠습니까?

연결된 UI 패키지도 사용하고 있으며 이 문제를 해결할 수 있었습니다.
UI(연결된 패키지)에서 반응 renderToString을 내보내야 합니다.
링크된 패키지에서 렌더링 기능을 만들었습니다.

더 나은 컨텍스트를 위해 - https://github.com/facebook/react/issues/14257

@theKashey 감사합니다. @gaearon 은 그게 정상적인 행동이라고 생각하는 것 같습니다. React가 두 번 로드되어서는 안 된다는 것을 알지만 링크된 로컬 패키지로 작업하는 데 권장되는 방법은 무엇입니까?

Lerna 작업 공간이 제대로 심볼릭 링크되는 문제도 있었습니다. 이것이 내가 이것을 작동시키는 데 사용한 트릭이었습니다. 나중에 npm install 를 실행해야 합니다.

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

이를 해결하는 방법은 여러 가지가 있으며 원사 해상도는 일반적으로 도움이 되지 않습니다. "빌드 도구"와 더 관련이 있습니다.

  • webpack의 경우 aliases 사용 - "하드" 별칭만 있으면 모든 것이 react 와 같이 단일 파일로 축소됩니다.
  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'))
});
  • 농담으로 moduleNameMapper 사용
"jest": {
    "moduleNameMapper": {
      "^react$": "<rootDir>/node_modules/$1",
    },

@theKashey 통찰력에 감사드립니다. 모듈 확인이 수행되는 방식(하단, 트리 상단)을 고려할 때 이는 이해가 되지만 사용자 관점에서는 이것이 매우 실용적이지 않다고 생각합니다. 패키지를 npm link 할 때 종속성을 명시적으로 다시 연결할 필요 없이 작동할 것으로 예상합니다. 이것은 로컬에서 패키지를 개발하는 것을 상당히 고통스럽게 만듭니다.

이것은 초석입니다. 이것이 node_modules 가 작동하도록 설계된 방식입니다. 이것이 두 개의 다른 주요 버전에서 Button 의 두 가지 버전을 가질 수 있고 종속 모듈이 "올바른" 것을 쉽게 찾을 수 있는 이유입니다. 패키지 버전.
이것이 항상 작동하는 방식입니다.

Node.js 내부는 매우 간단합니다. 알려진 모든 접두사(예 node_modules ) 또는 확장자(예 js , ts , json )를 추가하여 파일을 열어보십시오.

yarn pnp 이 작업을 수행하고 문제를 해결할 수 있습니다. yarn workspaces 는 패키지를 맨 위로 _hoist_ 공유할 수 있으며, "마법" 없이도 문제를 해결할 수 있습니다.

npm workspaces ? 현재 존재하지 않습니다.

실제로 작업 공간을 사용하도록 프로젝트를 전환했습니다. 분해능을 사용하지 않고도 이를 해결하고 호이스팅/구조물은 어쨌든 유익합니다.

이것은 머리를 긁는 사람이었습니다. webpack resolve.alias 설정을 시도했지만 작동하지 않았고 많은 설정도 시도했지만 불행히도 작동하도록 관리한 적이 없었지만 마침내 작동하도록 관리한 방법은 다음과 같습니다.

내 폴더 구조는 다음과 같습니다.

프로젝트
|
+-- 노드 모듈
|
+-- 빌드
| |
| +-- index.js
|
+-- 예시(create-react-app)
| |
| +-- 패키지.json

기본적으로 @jmlivingston 의 제안에 따라 프로젝트의 'main' node_modules에서 반응을 가져와서 예제 폴더 내에서 package.json을 수정해야 했습니다. 결과는 다음과 같습니다.

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

이제 그 후에 npm install 를 실행한 다음 npm link 를 실행 하여 트릭을 수행했습니다.

이것이 다른 사람을 돕고 시간을 절약할 수 있기를 바랍니다.

이 문제에 대한 수정 사항이 있습니까? 여기에서 가능한 한 많은 권장 사항을 시도했지만 운이 없었습니다. create-react-app 및 typescript를 사용하고 있습니다. React/React-dom 사용하기 16.8.3. 이것은 내가 2일 전에 만든 새 프로젝트이므로 매우 간단합니다. useSpring() 및 animated.div를 사용하고 있습니다. 감사 해요

@guru-florida 혹시 react-router를 사용 중이신가요?

나는 당신과 같은 스택(typescript & create-react-app)을 사용하고 있으며 render 속성에 문제가 있습니다. component 로 변경하면 효과가 있습니다.

전에:

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

후에:

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

도움이 되길 바랍니다..!

@mikeyyyyyy 아니요, 여기에는 React Router를 사용하지 않습니다. 내가 스프링을 사용하려고 시도한 마지막 프로젝트에 있었고 동일한 문제가 있었기 때문에 팁을 주셔서 감사합니다.

npm 링크(소포 앱에서)에 이 문제가 있었는데 npm link .../whatever/node_modules/react 로 해결되지 않는 것 같지만 후크가 아닌 구성 요소에서는 잘 작동합니다.

@tj ssr 에 문제가 있는 것 같습니다. 빠른 해결 방법은 연결된 패키지에서 반응 기능 또는 전체 반응을 내보내고 서버 패키지로 가져오는 것입니다.

@seeden 아 저는 SSR을 사용하지 않고 SPA w/ Parcel만 사용합니다. 내 자신의 물건과 내가 작업하고 있는 앱에 대해 내부적으로 ui pkg가 있습니다. 둘 다 동일한 react 버전을 가지고 있습니다. 중복이 있는 것이 이상해 보이지만 아마도 그것이 소포 문제일 것입니다.

@tj 아, 알겠습니다. 그럼 이 아주 이상한 문제에 행운을 빕니다. 나는 이것을 가지고 일주일을 보냈다.

이 문제에 대한 수정 사항이 있습니까?

여기에는 그 자체로 문제 가 없습니다. 이 페이지 에 설명된 대로 React는 $ react-dom 내부에서 "보이는" react 개체와 동일한 react 개체에 대한 useState() 호출이 필요합니다. 그것이 당신에게 일어나지 않는다면 그것은 페이지에 두 개의 React 사본을 번들로 묶는 것을 의미합니다. 이는 그 자체로 좋지 않으며 Hooks 이전의 다른 기능도 손상시킵니다. 그래서 어쨌든 수정하고 싶을 것입니다. 이 페이지 에는 문제를 해결하기 위해 진단하는 일반적인 방법이 포함되어 있습니다.

사람들이 이 문제에 직면했을 때 특정 해결 방법을 공유하기 위해 이 토론을 열어 둡니다. 그러나 당신이 아닌 다른 사람이 "고칠" 수 있는 문제 자체는 아닙니다.

npm 링크(소포 앱에서)에서 이 문제가 발생했습니다. npm 링크 .../whatever/node_modules/react 해결되지 않는 것 같지만 후크가 아닌 구성 요소에서는 잘 작동합니다.

작은 재현 케이스를 만들어 주시겠습니까?

@gaearon 이 할 것입니다, 다음 주에 조금 더 파고들 시간이 있어야 합니다

다행히 require-controlyarn link + SSR + styled-components 4의 정적 컨텍스트 문제를 해결했습니다. @theKashey 감사합니다 👍

나는 여기에서 모든 것을 시도했지만 실패했습니다. 실제로 여기에 문서화되지 않은 다른 것이었습니다. 그것은 react imports의 대소문자 구분과 관련이 있습니다. 어떤 경우에는 다음을 수행했습니다.

import React from 'react'

그리고 다른 사람들:

import React from 'React'

일부 파일 시스템(unix, osx)에서는 이로 인해 Webpack이 두 개의 React 복사본을 인스턴스화합니다.

이것은 우리에게 React 사본이 하나만 있다는 것을 분명히 알 수 있었기 때문에 극심한 혼란을 야기했습니다. 그러나 그것은 우리가 그것을 수입하는 방식이었습니다.

반응 문서에 대한 테스트도 분명히 소문자만 사용하기 때문에 잘 나옵니다.

이것은 문서에서 언급할 가치가 있는 것처럼 들립니까?

저에게 React의 여러 인스턴스가 있는 이유는 Webpack DllPlugin이었습니다. 내 공급업체 DLL의 경우 내 항목 목록에 reactreact-dom 를 포함하지 않았지만 react 또는 react-dom 가 필요한 다른 라이브러리가 있으므로 내 DLL에는 reactreact-dom 가 포함되어 있습니다(매니페스트 json 파일을 빠르게 확인하면 알 수 있음). 따라서 코드를 실행하고 React를 애플리케이션으로 가져올 때 node_modules 에서 로드했지만 공급업체 코드에서는 DLL 파일에서 React가 필요했습니다.

전체 : DLL 파일에 주의하고 포함된 모듈에 필요하지 않은 추가 종속성이 포함되어 있지 않은지 확인하십시오. 그렇지 않으면 두 번 가져올 것입니다.

react-hot-loader4.6.0 로 업데이트하여 이 문제를 해결할 수 있었습니다.

이것은 Parcel의 npm link 에 대한 트릭을 수행했습니다.

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

그것이 프로덕션 빌드에 사용하려고 시도하는 것인지 확실하지 않지만 일종의 해킹처럼 보이지만 적어도 개발에는 작동합니다.

@theKashey 세상에, 작동합니다! 나는 사람들이 이 문제와 관련하여 제안하는 다양한 솔루션을 시도했습니다: package.json deps로 맹글링, 프로젝트 전체에서 "2개의 반응" 추적, 내가 *훅 규칙`을 어기고 있는지 확인 아닙니다), 하지만 다음과 같은 옵션 이 있다고 생각합니다.

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

app-as-a-lib의 후크를 사용하여 프로젝트를 다음 레벨로 이동할 수 있습니다.

이것은 결과 webpack.config.js 입니다.

npm ls react

보고

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

나를위한

console.log(window.React1 === window.React2) 는 true를 반환합니다.
이 시점에서 나는 그것이 문제를 일으키는 SSR이라고 생각합니다.

업데이트. 그것은 실제로 React-apollo의 SSR 동작으로 인해 발생했습니다(https://github.com/apollographql/react-apollo/issues/2541).
2.3.1로 업그레이드하면 해결되었습니다.

안녕하세요 여러분, 우리 팀은 이 문제에 직면했고 해결하는 데 며칠이 걸렸습니다.

우리를 위한 작업 솔루션

솔루션 A: 위에서 언급한 대로 찾을 패키지 위치 지정

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

솔루션 B: webpack resolve.modules 를 사용하여 모듈을 찾을 올바른 node_modules 폴더의 우선 순위를 지정하십시오.

사건의 배경과 그 이유

먼저 react의 잘못이 아니며 lerna의 잘못도 아니지만 react, webpack 및 npm-link가 일부 책임을 져야 할 수도 있습니다.

케이스 요구 사항:

-비 모노레포:

  • 심볼릭 링크 된 패키지가 있습니다
  • 심볼릭 링크된 패키지가 후크를 사용하여 구성 요소를 내보냈습니다.
  • 반응 클라이언트 측 페이지 생성

    • 모노레포에서 작업하는 경우

  • 심볼릭 링크된 패키지
  • 패키지에는 다른 버전의 종속성이 있으므로(패치 버전 차이도 있음) 2개의 반응이 설치된 경우 작업 공간도 해결됩니다.
  • 입구 패키지는 후크를 사용하는 심볼릭 링크된 패키지를 가져왔습니다.

예시

구조

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

작업 공간으로 부트스트랩하면 다음으로 해결됩니다.

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

그리고 웹팩이나 다른 것으로 ProductA 를 제공하면 2개의 반응 인스턴스가 포함됩니다.

ProductA의 코드는 ProductA/node_modules/react 를 찾습니다.

그러나 가져온 ComponentWithHooks는 mono repo root/node_modules/react 를 찾습니다.

왜요? npm의 조회 규칙을 기억하십니까? 자신의 node_modules 폴더에서 모듈을 찾을 수 없으면 부모의 node_modules...

따라서 webpack과 같은 도구는 기본적으로 이 규칙을 완벽하게 적용했습니다.
모노 레포 솔루션이 대중화되는 것은 잘못된 것이 아닙니다.
그리고 일반 패키지는 이것을 눈치채지 못할 것입니다. 대부분은 react 및 redux와 같은 단일 인스턴스가 필요하지 않습니다.

원사 작업 공간 예제를 사용하여 매우 기본적인 재생산을 사용하여 이와 동일한 문제를 겪고 있습니다. - https://github.com/mwarger/yarn-workspace-hooks-repro

typescript로 작성되고 소포와 함께 번들로 제공되는 component-library 가 있습니다. example-demo 는 이 component-library 를 선보일 것이며 새로 만든 CRA 앱입니다. 모든 일반 패키지는 얀으로 들어 올려져 있으므로 이론상으로는 사용 가능한 반응 버전이 하나만 있어야 합니다. 그러나 index.tsx에서 React.useEffect 호출을 하면 이 GitHub 문제가 발생하는 오류가 발생합니다.

후크가 추가될 때까지 모든 것이 작동합니다. 오류를 재현하려면 component-library/src/index.tsx 에서 7-9행의 주석 처리를 제거하십시오.

바라건대 내가 간과했던 어리석은 일을하고 있습니다. 이 문제를 해결하기 위해 사용할 수 있는 모든 단계에 대해 조언해 주십시오. 감사합니다!

후속 편집: 아래 제안된 디버그 스크립트 출력은 저에게 true 를 인쇄합니다. 두 개의 React가 없는 것 같습니다.

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

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

몇 시간이 걸렸으므로 여기에 메모하는 것이 좋습니다.

제 경우에는 HTML 템플릿의 헤드에 <script defer src="./dist/bundle.js" /> 라인을 넣었습니다. 이것은 React hooks를 사용하지 않을 때 정상적으로 작동합니다. 모든 솔루션이 작동하지 않으며 이 경우 window.React1 == window.React2 검사는 true 를 반환합니다.

webpack은 이후에 스크립트 태그를 삽입하므로 템플릿 자체에 스크립트 태그가 없어야 합니다. 템플릿에서 스크립트 태그를 제거하여 React가 후크(말장난 의도)로 다시 작동하도록 합니다.

제 경우에는 내가 작업하고 있던 종속성에 연결된 npm인 React 앱이 있습니다. reactreact-dom 를 dev 및 peer dep로 이동해야 하는 몇 가지 종속성을 수정할 수 있을 때까지 이것은 트릭을 수행합니다.

  1. 앱에서: cd node_modules/react && npm link
  2. 앱에서: cd node_modules/react-dom && npm link react
  3. 연결된 패키지에서: npm link react

작동하는 이유는 무엇입니까? 오류 경고 페이지 에는 "후크가 작동하려면 애플리케이션 코드의 반응 가져오기가 react-dom 패키지 내부의 반응 가져오기와 동일한 모듈로 확인되어야 합니다"라고 언급되어 있습니다.

위의 모든 것을 시도해도 여전히 이 문제가 발생합니다. preset-envpreset-react 플러그인이 있는 표준 webpack4/babel 구성. 내 react/react-dom 버전은 원사 해상도를 사용하여 $ window.React1 === window.React2 16.8.4 true 고정되어 있습니다.

이것은 가장 기본적인 사용법입니다.

import React, { useState } from "react";

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

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

다른 아이디어가 있는 사람이 있습니까?

편집: 명확히 하기 위해 오류는 OP에 따라 react.development.js:88 Uncaught Invariant Violation: Hooks can only be called inside the body of a function component. 로 표시됩니다.

제 경우에는 내가 작업하고 있던 종속성에 연결된 npm인 React 앱이 있습니다. reactreact-dom 를 dev 및 peer dep로 이동해야 하는 몇 가지 종속성을 수정할 수 있을 때까지 이것은 트릭을 수행합니다.

  1. 앱에서: cd node_modules/react && npm link
  2. 앱에서: cd node_modules/react-dom && npm link react
  3. 연결된 패키지에서: npm link react

작동하는 이유는 무엇입니까? 오류 경고 페이지 에는 "후크가 작동하려면 애플리케이션 코드의 반응 가져오기가 react-dom 패키지 내부의 반응 가져오기와 동일한 모듈로 확인되어야 합니다"라고 언급되어 있습니다.

감사 해요! 이것은 나를 위해 잘 작동합니다. (npm link와 symlink 혼합 상황을 사용하는 경우에도)

위에서 제안한 모든 것을 시도했지만 여전히 오류가 발생했습니다.

@inverherive 의 약간의 도움으로 enzyme-adapter-react-16 이 여전히 문제를 일으키는 것으로 나타났습니다.

react-test-renderer 를 최신 버전(16.8.4)으로 업데이트했는데 최근에 후크 지원이 추가되었기 때문에 npm ls react-test-renderer enzyme-adapter-react-16 의 최신 버전(1.11.2 ) 후크를 지원하지 않는 [email protected] 의 내부 종속성이 있습니다.

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

이 문제를 수정하고 @chulanovskyi수정 사항 을 따르기 위해 우리는 yarn을 사용할 때 package.json에 react-test-renderer 해상도를 추가했습니다. 이렇게 하면 react-test-renderer 의 모든 참조가 "16.8.4"를 사용하게 됩니다.

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

이것은 매우 실망 스러웠습니다. 이것이 다른 사람을 도울 수 있기를 바랍니다. 제안을 해주신 @chulanovskyi@theKashey 에게도 감사드립니다.

이것은 react 및 react-dom을 dev 및 peer dep로 이동해야 하는 몇 가지 종속성을 수정할 수 있을 때까지 트릭을 수행합니다.

@ajcrews (뭔가 놓쳤을 수도 있지만) 내부 라이브러리에 npm link react peerDependenciesdevDependencies 에 react가 있고 여전히 귀하의 오류 해결에 관계없이 수정합니다. 좋은 발견!

게시하려고했지만 해결책을 찾았습니다.

개발을 위해 내부에 예제 CRA 앱이 있는 구성 요소 라이브러리가 있습니다.

CRA 앱의 package.json에서 루트 구성 요소의 package.json에서 "빌려오도록" react 및 react-dom을 수정해야 했습니다.

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

이것은 매우 실망 스러웠습니다. 이것이 다른 사람을 도울 수 있기를 바랍니다. 제안을 해주신 @chulanovskyi@theKashey 에게도 감사드립니다.

@Paddy-Hamilton 설치 후에는 항상 잠금 파일을 확인하십시오. yarnreact-test-renderer 을 복제하는 것과 동일한 문제가 발생했습니다. 잠금 파일에서 약간의 수술을 통해 다음을 수정할 수 있습니다.

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"

yarn check 는 이미 경고합니다.

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

그런 다음 다음 패치를 적용하여 수동으로 중복 제거하십시오.

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

이제 resolutions 또는 webpack 별칭이 없는 react-test-renderer 의 단일 버전이 있습니다.

링크된 패키지 및 create-react-app 와 관련된 모든 문제는 facebook/create-react-app#6207을 팔로우하세요.

이를 해결하는 방법은 여러 가지가 있으며 원사 해상도는 일반적으로 도움이 되지 않습니다. "빌드 도구"와 더 관련이 있습니다.

  • webpack의 경우 aliases 사용 - "하드" 별칭만 있으면 모든 것이 react 와 같이 단일 파일로 축소됩니다.
  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'))
});
  • 농담으로 moduleNameMapper 사용
"jest": {
    "moduleNameMapper": {
      "^react$": "<rootDir>/node_modules/$1",
    },

이것은 나를 위해 그것을 했다.

@ajcrews
감사합니다! 나에게 훌륭하게 작동합니다!

react 16.8.6, electron-webpack 및 RHL을 사용하여 최소한의 설정으로 작은 테스트 케이스를 만들었습니다. 특히, 이 오류가 발생하면 전체 브라우저(이 설정에서 전자)가 CPU 시간 전체를 사용하기 시작합니다)

https://github.com/PerfectionCSGO/reeee

나는 지금 3 일 동안이 문제에 대해 머리를 강타했습니다. 원래 RHL이 문제라고 생각했지만 이 프로젝트에서 RHL을 완전히 제거해도 문제가 해결되지 않습니다.

npm ls react는 하나의 결과만 반환합니다. 위의 수정 사항이 최신 버전 + webpack 별칭으로 적용되었는지 확인했습니다.

코드는 샌드박스에서 작동합니다.

간단한 웹팩/웹사이트에서 코드는 문제 없이 작동합니다. 그러나 electron-webpack을 사용하면 이 문제가 지속됩니다.

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

누군가 나에게 포인터를 줄 수 있기를 바랍니다 ...

react-l18next를 mobx-react-lite로 교체하고 관찰자를 사용하면 동일한 효과가 발생합니다.

내 문제와 관련하여 전자-웹팩을 팔꿈치로 하여 문제를 해결하고 보다 '순수한' 전자 솔루션을 사용합니다. 내 생각에 그것은 호환되지 않는 webpack 또는 babel에서 사용되는 도구 체인입니다.

이 문제는 프로덕션에서만 발생했습니다. 여기에 제안된 솔루션 중 어느 것도 도움이 되지 않았습니다.
제 사용 사례는 다른 웹사이트에서 위젯으로 로드되는 타사 앱이었습니다.
사이트가 위젯과 함께 처음 로드되었을 때 모든 것이 잘 작동했지만 사용자가 다른 페이지로 이동하여 위젯이 있는 페이지로 돌아올 때 후크 오류가 발생했습니다.

이 오류는 탐색으로 인해 페이지를 새로고침하지 않는 경우에만 발생합니다.

문제가 무엇인지 알아내려고 몇 시간을 보냈습니다. 마지막으로 문제는 앱 번들을 로드하는 코드 스니펫에 있었습니다. 페이지 변경 시 번들이 여러 번 로드될 수 있으므로 동일한 이름 공간에 여러 React 인스턴스가 있는 것 같습니다.

스크립트가 이미 로드되었는지 확인하여 수정했습니다.
먼저 Webpack의 '라이브러리' 구성을 사용하여 내 라이브러리를 전역 네임스페이스로 내보냈습니다.

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

그런 다음 로딩 스크립트에서 라이브러리가 있는지 여부를 확인했습니다.

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

매우 구체적인 사용 사례일 수 있지만 이것이 다른 사람을 도울 수 있기를 바랍니다.

그래서 우리는 웹팩을 활용하는 주요 React 애플리케이션을 가지고 있습니다.
후크를 사용하는 작은 React 라이브러리를 만들려고 하고 번들러(소포, 순수 babel, webpack)를 교체하려고 했습니다.
웹팩 구현을 시도할 때 react 및 react-dom을 외부로 표시했으므로 번들에 포함하지 않습니다.
npm 링크를 사용할 때 여전히 동일한 후크 예외가 발생합니다.

기본 애플리케이션의 반응에 대한 심볼릭 링크를 만드는 것은 작동하지만 훌륭한 개발 워크플로는 아닙니다.

문제의 근본 원인을 파악하는 데 어려움을 겪고 있습니다. 중복 React 인스턴스를 생성하는 것은 무엇입니까?

@adriene-orange 안녕하세요. 자세한 설명은 내 게시물 https://github.com/facebook/react/issues/13991#issuecomment -472740798을 참조하세요.

npm 링크로 인한 다중 인스턴스는 패키지에서 찾을 수 없는 경우 기본적으로 노드가 상위 폴더의 node_modules에서 모듈을 조회하기 때문입니다.

이에 대한 가장 간단하고 최상의 솔루션은 입구 패키지의 웹팩(또는 기타 도구) 구성에 있습니다. 웹팩이 모듈을 찾을 경로와 순서를 수동으로 설정하는 resolve.modules 와 같은 것이 있습니다. Exp., resolve: { modules: [path.resolve(PACKAGE_ROOT, 'node_modules'), 'node_modules'] } 는 webpack이 입구 패키지 루트의 node_module에서 먼저 모듈을 찾도록 합니다. 루트에서 모듈을 찾을 수 없으면 상대 node_modules 폴더에서 찾으십시오...

그래서 우리는 웹팩을 활용하는 주요 React 애플리케이션을 가지고 있습니다.
후크를 사용하는 작은 React 라이브러리를 만들려고 하고 번들러(소포, 순수 babel, webpack)를 교체하려고 했습니다.
웹팩 구현을 시도할 때 react 및 react-dom을 외부로 표시했으므로 번들에 포함하지 않습니다.
npm 링크를 사용할 때 여전히 동일한 후크 예외가 발생합니다.

기본 애플리케이션의 반응에 대한 심볼릭 링크를 만드는 것은 작동하지만 훌륭한 개발 워크플로는 아닙니다.

문제의 근본 원인을 파악하는 데 어려움을 겪고 있습니다. 중복 React 인스턴스를 생성하는 것은 무엇입니까?

안녕하세요 이 오류가 발생합니다

불변 위반: 잘못된 후크 호출입니다. 후크는 함수 구성 요소의 본문 내부에서만 호출할 수 있습니다. 다음 이유 중 하나로 인해 발생할 수 있습니다.
1. React와 렌더러(예: React DOM)의 버전이 일치하지 않을 수 있습니다.
2. Hooks의 규칙을 위반할 수 있습니다.
3. 같은 앱에 두 개 이상의 React 사본이 있을 수 있습니다.
이 문제를 디버그하고 수정하는 방법에 대한 팁은 https://fb.me/react-invalid-hook-call 을 참조하십시오.

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

샘플 코드 https://stackblitz.com/edit/react-mbze9q

테스트 케이스 내에서 이 기능에 액세스하려고 하면 위의 오류가 발생합니다.

@abhishekuru 테스트에서 구성 요소 외부에서 Hook을 호출하고 있습니다.

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

오류 상태에서 후크는 다른 후크 또는 구성 요소 내에서만 호출할 수 있습니다. 귀하의 경우 테스트용 구성 요소를 만들고 원하는 경우 후크를 사용하는 해당 구성 요소를 렌더링할 수 있습니다.

뻔뻔한 플러그

@abhishekuru 여러 구성 요소 간에 사용되는 일반 후크가 있고 특정 구성 요소와 독립적으로 테스트하려는 경우 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);
});

SSR에만 문제가 있었기 때문에 여기에 차임하고 싶었습니다. 파일 변경 시 노드의 require.cache 를 지웁니다. 이것은 효과적으로 서버에 핫 리로딩을 제공합니다. 노드의 require.cache 를 지우면 단일 복사본이 필요한 라이브러리에 문제가 발생합니다. 솔루션은 다음과 같습니다.

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

isSingleton 함수에는 단일 복사본이 있어야 하는 라이브러리 목록이 포함되어 있습니다. 좋은 경험 법칙은 peerDependencies 에 정의해야 하는 라이브러리입니다.

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

또한 같은 문제가 있었고 나를 위해

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

또한 true 를 반환하고 주어진 제안을 모두 시도했지만 아무 것도 작동하지 않았습니다. 마침내 다음과 같이 밝혀졌습니다.

Webpack은 bundle.js 가 있는 스크립트 태그를 index.html 에 자동으로 추가합니다. 내 문제는 bundle.jsindex.html 에 명시적으로 추가 했기 때문에 발생했습니다. 이는 후크 전에 잘 작동했습니다.

나에게 문제는 babel 7 업그레이드 후 npm ls react가 있는 별도의 버전이 없었습니다. 풀이
.babelrc의 "react-hot-loader/babel"이 문제를 일시적으로 수정했습니다.

위의 모든 솔루션을 시도했지만 여전히 오류가 발생했습니다.
결국 why-did-you-update 패키지로 인해 발생했으며 관련 문제 가 있음을 발견했습니다. React를 수정하는 유사한 패키지를 사용하는 사람을 위한 단서입니다.

react-native + Yarn Workspaces 시나리오에서 이 문제를 해결할 수 있었습니다.


루트 package.json

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

이것은 react-native 코드가 호이스트되는 것을 방지합니다(리액트 네이티브에 필요한 것처럼). 여전히 react 를 호이스팅하므로 모든 공유 모듈이 동일한 반응을 사용합니다.


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

메트로 구성을 통해 번들러는 모든 것이 어디에 있는지 알 수 있습니다.

예를 들어 로컬에서 npm 패키지를 개발하는 사람들을 위해 문제를 해결하는 방법을 찾았고 그들은 일종의 예제 앱에서 npm 링크를 사용하여 패키지를 로드하여 로컬에서 테스트하려고 합니다.

예제 앱(구성 요소를 테스트하는 원래 방법)에서 Storybook 으로 전환했습니다. 프로젝트에서 스토리북을 사용할 때 컴포넌트가 사용하는 것과 동일한 것을 사용하므로 React를 두 번 로드하지 않습니다. npm 링크를 사용하는 동안 후크와 React가 두 번 로드되는 문제가 있었고 위의 솔루션 중 어느 것도 작동하지 못했습니다. 그래서 Storybook은 내 문제를 해결했고 이제 여러 시나리오를 통해 내 구성 요소를 테스트하고 동시에 이에 대한 몇 가지 대화형 문서를 작성할 수 있습니다.

이에 대한 내 경험을 공유하여 구성 요소 라이브러리에 대해 webpack 외부 를 사용하여 빌드에서 reactreact-dom 를 제외하여 프로젝트에서 해결했습니다.

우리는 이제 막 React로 시작합니다. 제 경우에는 Neutrino 구성 요소 라이브러리 패키지와 Neutrino webapp 클라이언트 패키지가 있는 Lerna monorepo로 시작합니다. 웹앱은 연결된 구성 요소 라이브러리의 빌드 제품을 사용합니다. 몇 가지 실험을 하고 동일한 React 인스턴스에 대해 true #$를 얻은 후, 구성 요소 라이브러리 빌드에서 reactreact-dom 를 전혀 제외하는 방법을 찾았습니다.

webpack 구성 요소 라이브러리에 대한 일반적인 디자인 패턴 솔루션 인 것 같으므로 구성 요소 라이브러리에서 webpack 구성에 추가했습니다.

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

reactreact-dom 에 대한 webapp 패키지에 전역 스크립트 태그를 넣을 필요가 없었습니다. Webpack이 webapp에 제공하는 것과 동일한 require 구현에서 구성 요소 라이브러리에 이를 제공하고 있다고 생각합니다.

이 오류의 또 다른 원인은 React Router의 Route 를 잘못 구성하는 것입니다.

이것은 실패합니다 .

<Route render={MyHookedComponent}/>

하지만 이것은 성공합니다 .

<Route component={MyHookedComponent}/>

예. render component 를 사용해야 합니다. render 는 일반적으로 클래스 기반 구성 요소에서 잘 작동하기 때문에 이것은 저지르기 쉬운 실수입니다.

나는 biolerplate에서 작업하고 있었고 그것을 npm에 게시하고 npm link 의 도움으로 개발하고 있었습니다. 제대로 작동했지만 언젠가는 Invalid Hook call warning 오류가 발생하기 시작했습니다.
npm link ../myapp/node_modules/react를 사용해 보았지만 문제가 해결되지 않았습니다.
그리고 React1 === React2 를 비교해보면 사실이고 npm ls react 도 완료되어 하나의 패키지만 보여줍니다.

그리고 저는 webpack도 사용하지 않고 있습니다. create-react-app 외부에 일부 레이어를 추가하기만 하면 앱이 로컬에 설치된 반응 모듈을 사용하도록 강제할 수 없습니다.
지난 3일부터 막혔습니다._

@hnagarkoti 와 동일합니다.

react-apollo 의 이전 버전을 사용하고 있었기 때문에 서버 측 렌더링(SSR) 중에 이 경고가 발생했습니다. 그래서 이 문제에 직면하는 다음 불쌍한 영혼을 돕기 위해 이 링크를 여기에 남겨두고 싶었습니다.

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

간단히 말해서 getDataFromTree[email protected] 버전까지 반응 후크를 지원하지 않습니다.

나는 같은 문제가 있었고 다음을 추가하여 해결했습니다.

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

내 메인 앱의 webpack 구성에서 resolve 속성으로 변경합니다.

두 개의 React 사본을 사용한 것은 분명히 내 실수였지만 오류 메시지가 더 좋았더라면 좋았을 것이라는 데 동의합니다. 나는 이것이 아마도 다음과 유사하다고 생각합니다. #2402

create-react-app으로 이 작업을 수행하기 위한 제안 사항이 있습니까?

^ 좋아, create-react-app에 대해 이 문제를 해결하기 위해 내가 간 솔루션은 react-app-rewired사용자 정의-cra를 사용하는 것입니다.

내 config-overrides.js는 다음과 같습니다.

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

const path = require('path'); 

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

예제 프로젝트: https://github.com/dwjohnston/material-ui-hooks-issue/tree/master

우리 팀에는 수십 개의 앱에 걸쳐 보편적인 탐색 구성 요소 작업이 있습니다. 이러한 모든 앱은 반응 15.0.0에서 반응 16.8.0까지입니다. 후크 위에 구현된 탐색을 활성화하려면 최신 반응과 번들로 묶어야 합니다.

이 경우 react의 여러 인스턴스를 갖는 것이 우리의 기본 요구 사항입니다. react 공식 팀에서 향후 이 문제를 해결할 의향이 있는지 알고 싶습니다.

@dwjohnston create-react-app 에 대한 내 해결 방법은 개발을 위한 웹팩 구성을 만드는 것이었습니다. create-react-app 는 내부적으로 webpack, webpack-dev-server 및 babel-loader를 사용하므로 개발을 위한 webpack 구성을 만드는 것도 나쁘지 않습니다. 올바르게 작동합니다.

create-react-app 에 문제가 있습니다. https://github.com/facebook/create-react-app/issues/6953 webpack alias 지원 또는 이와 유사한 것을 추가하십시오.

👋 create-react-app 를 사용 중이고 이 문제를 겪고 있는 사람이 있다면 그 문제에 대해 엄지손가락을 치켜세워 주시겠습니까?

@ricokahler - 지적해주셔서 감사합니다. 이 문제를 겪고 있는 유일한 사람이 아니라는 사실을 알게 되어 기쁩니다. 컨텍스트에서도 문제가 발생했습니다.

이 문제를 추가로 논의하기 위해 알고 있는 리소스가 있습니까?

내 보트에 있다면 로컬 디렉토리에서 반응 구성 요소 패키지를 추가했으며 이제 node_modules의 자체 복사본과 함께 자동으로 빌드 및 설치합니다(이를 수행하기 위해 npm 링크를 사용하기 때문에). 앱 2 사본 또는 지금 반응하십시오.

node_modules/를 삭제하여 문제를 해결했습니다./node_modules 앱을 실행하기 전에. 이 작업을 자동으로 수행하려면:

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

SSR을 할 때도 이런 문제에 직면했습니다.
로컬에서 React 라이브러리를 테스트하기 위해 Lerna 를 사용하는 경우 라이브러리에 "react/react-dom/react-router"를 peerDependencies로 추가할 수 있지만 devDependencies로 추가 해서는 안 됩니다. (이렇게 하면 중복됩니다)
node --preserve-symlinks 를 사용하여 peerDependencies를 설치하는 상위 리포지토리를 조회할 수 있습니다.
jest의 경우 "jest.moduleDirectories" 옵션에 상위 저장소 경로를 추가해야 Jest가 이를 해결할 수 있습니다.

@apieceofbart 그것은 나를 위해 작동합니다, thx!

예를 들어 JS 모듈을 사용하여 외부 React 구성 요소를 로드할 때 이 오류가 발생했습니다. 그들은 완전히 프로젝트 외부에 있으며 동적 import()로 로드됩니다(추가 지원을 위한 jsonp). 이 문제를 해결하기 위해 React를 각 모듈에 속성으로 전달/주입합니다. 이것은 작동하지만 각 모듈은 포함하는 React 앱에 종속됩니다. 종속성을 제거하려고 합니다.

다른 사람들이 언급했듯이 이 속성은 모든 유형의 마이크로 프런트 엔드에 사용할 수 있는 React를 제거합니다. 문제는 라이브러리로 사용하기 위해 React를 가져올 때 JS 런타임에서 전역 상태를 생성하는 이러한 부작용이 있다는 것입니다.

간단한 사용 사례의 경우 부작용이 있다는 것은 React가 "사용하기 더 쉽다"는 것을 의미한다는 것을 이해합니다. 그러나 웹 페이지가 여러 번들 단계의 여러 스크립트로 구성되면 그 중 하나는 React를 설정할 수 있어야 하고(해당 부작용을 명시적으로 수행) 나머지는 단순히 라이브러리 함수를 호출할 수 있어야 합니다.

여전히 react-bootstrap에 문제가 있습니다. # https://github.com/react-bootstrap/react-bootstrap/issues/3965

React용 라이브러리를 만들려고 애쓰는 다른 사람을 위해 https://github.com/whitecolor/yalc 를 시도해보세요. 심볼릭 링크보다 훨씬 잘 작동합니다.

@mpeyper 는 잘 작동합니다. 고마워

@pieceofbart 그것은 나를 위해 일했습니다. 제안해 주셔서 감사합니다. 👍

나에게 이 문제는 PowerShell에서 내 프로젝트 디렉터리로 이동하고 경로에서 디렉터리 이름을 대문자로 지정하지 않았을 때 발생했습니다. Users/.../... 대신 users/.../...에서 프로젝트를 만들었습니다.
대소문자 오류를 수정하고 프로젝트를 다시 만들면 문제가 해결되었습니다.

나를 위해:

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

대부분 수정했지만 충분하지 않아 hooks can only be called inside the body of a function component 오류가 계속 발생했습니다.

내 라이브러리의 일부 구성 요소가 다음과 같이 내보냈기 때문입니다.

export default Radium(withTranslation()(MyComponent))

:엑스:

여기서 withTranslation 는 react-i18next의 HOC이고 Radium 는 Radium의 HOC입니다.

그리고 다음과 같이 내보내기:

export default withTranslation()(Radium(MyComponent))

:heavy_check_mark:
모든 것을 고쳤습니다.

react-i18next는 React Hooks를 사용하는 버전 10에 있었습니다.

@mikeaustin 우리도 같은 문제를 겪고 있습니다. "React를 각 모듈에 속성으로 전달/주입"한 예가 있습니까?

여전히 이 문제가 발생하면 모든 단계를 시도했습니다.

  • 원사 작업 공간(lerna를 통해)
  • 하나의 반응 dep가 있는지 확인했습니다. 예

영향을 미칠 수 있는 몇 가지 사항:

  • libraryTarget과 함께 웹팩 사용
  • 타이프스크립트를 사용하여
$ npm ls react-dom
/xxx
└── [email protected]

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

루트 패키지.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 나는 같은 문제가 있었고 그것은 나를 위해 일했습니다. 감사합니다.

아래와 같이 package.json에 "prestart"를 추가합니다.

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

나는이 문제가 있었고 여러 버전의 react / react-dom으로 인한 것이 아닙니다.
내가 사용하는 사용자 지정 도구에서 필요 캐시가 지워지고 있었습니다(이 논의 이외의 목적으로). 예:

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

그래서 만약 당신이 이와 같은 일을 하고 있다면 - 그것은 React Hooks에 영향을 미칠 것이므로 가능하면 피하세요.

나는 같은 문제가 있었고 다음을 추가하여 해결했습니다.

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

내 메인 앱의 webpack 구성에서 resolve 속성으로 변경합니다.

두 개의 React 사본을 사용한 것은 분명히 내 실수였지만 오류 메시지가 더 좋았더라면 좋았을 것이라는 데 동의합니다. 나는 이것이 아마도 다음과 유사하다고 생각합니다. #2402

Parcel을 사용하는 사람의 경우 컴파일된 파일이 dist 인 경우 다음을 추가해야 합니다.

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

package.json 로 이동한 다음 로컬 개발/테스트를 위해 여전히 link (npm 또는 yarn) 라이브러리를 사용할 수 있습니다.

@mikeaustin 우리도 같은 문제를 겪고 있습니다. "React를 각 모듈에 속성으로 전달/주입"한 예가 있습니까?

React Context를 사용하여 "React" 자체를 전달하고 HoC를 만들어 모든 구성 요소에 속성을 주입할 수 있습니다. api.React와 같은 API에서는 무엇이든 전달할 수 있지만 이러한 구성 요소 주위에 HoC를 래핑하는 것은 약간 까다롭습니다(이제 구성 요소 내에서만 사용할 수 있고 내보낼 수 없기 때문입니다.

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

소스 코드를 변경하여 오류 메시지를 변경하고 더 많은 정보를 추가하는 것이 쉽지 않고 더 많은 시간이 필요한 경우 적어도 이 메모를 문서 에 추가하는 데 몇 시간을 할애합니다.

_p.s: react에는 훌륭한 문서가 있지만 해당 페이지는 검토가 필요하다고 생각합니다._

@OliverRadini

react-hot-loader^4.6.0 로 업데이트하여 이 문제를 해결할 수 있었습니다.

Maaan, 해결했습니다.
@gaearon @theKashey 이것을 https://reactjs.org/warnings/invalid-hook-call-warning.html 에 추가하여 react-hot-loader 의 이전 버전으로 인해 사람들이 시간을 낭비하지 않도록 하는 것은 어떻습니까?

이미 12개의 문제에 걸쳐 문서화되어 있다고 생각했습니다.

안녕하세요, 저는 라이브러리 모두에서 React를 사용하고 있습니다. 앱 내 라이브러리를 사용합니다. 다음을 사용하여 두 개의 반응 인스턴스 문제를 해결했습니다.

웹팩 구성에서:

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

라이브러리 웹팩 구성에서

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

그래서 트랜스파일되지 않은 파일(*.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;

"JSX 파일로 이동하고 변환"이 아니라고 가정하면 조언이 있습니까?

자극과 반응을 혼합하여 사용하는 저에게는 효과가 없는 것 같습니다. 하이브리드 앱이 있고 후크를 사용하기 시작했는데 터보링크를 추가하기 시작하자마자 실패했습니다.

편집: 지금은 사용 중인 스크립트 태그에 data-turbolinks-track="reload" data-turbolinks-eval="false" 를 추가하여 문제를 해결했습니다.

동일한 질문이 있습니다. 4시간 후, jenkins util이 변환 .babelrc 파일을 서버로 누락했다는 사실을 알게 되었습니다.。。。

오류가 발생하는 이유는 무엇입니까?

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

react-dom 버전이 무엇인지 확인하십시오.

$ npm ls 반응돔
[email protected] /mnt/g/development/javascript/pow-vehmain
└── [email protected]

라이브러리에서 connect(mapStateToProps)(MyComponent)를 내보내고 내 CRA 앱에서 해당 라이브러리를 사용할 때 이 문제에 직면했습니다.

아니, 이건 내 잘못이었다. 이것을 호출한 루틴은 react-router-dom을 사용했고 컴포넌트가 아닌 render prop을 사용했습니다.

당신 중 누구라도 같은 문제가 있었지만 개츠비와 관련이 있습니까?

'npm ls react' 후 다음과 같은 결과를 얻습니다.
image

및 'npm ls react-dom'
image

처음에는 실수로 react를 전역적으로 설치했다고 생각했는데 전역적으로 제거한 후 아무 것도 변경되지 않았습니다. 그런 다음 다른 디렉토리인 'gatsby new random-name'에 완전히 새로운 프로젝트를 만들고 작은 기능을 추가했습니다(https://www.youtube.com/watch?v=asrdFuAxPaU&feature=youtu에 따라 댓글 추가). .be)를 gatsby-starter-default에 추가하여 오류가 자체적으로 재현되는지 테스트합니다. 유감스럽게도, 그랬습니다!

어떤 조언이든 좌절한 평민들은 잘 받아들일 것입니다.

나는 여전히 스토리북에서 이 문제에 직면하고 있다. npm ls의 이 출력이 정확합니까?
imageimage

제 경우에는 why-did-you-update 모듈로 인해 문제가 발생했습니다.

작업 공간과 lerna monorepo를 사용하고 패키지를 들어올립니다. 문제를 해결할 것입니다.

우리는 SSR과 같은 문제를 겪고 있습니다. webpack 구성에서 externals: [“react”] 를 설정한 다음 수동으로 react/umd/react.development.js 를 로드하여 작동하는 것 같습니다. 그러나 이것은 고통스러운 일이며 더 간단한 방법을 찾고 싶습니다.

좋아, 이것이 누군가를 돕기를 바랍니다. 실수로 webpack runtime.js를 여러 번 로드하여 React의 여러 복사본이 존재하게 되었습니다. runtimeChunk(runtime.js)를 한 번만 로드해야 합니다.

저와 같은 Jest 테스트에 문제가 있는 경우 이것이 저를 위해 해결되는 것 같습니다.
jest.config.js 에 이것을 추가하십시오.

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

이 오류가 적어도 발생한 파일을 가리키면 좋을 것입니다. 실수로 일반 함수에서 후크를 호출했는데 디버그하기 어려웠습니다.

문제의 또 다른 원인과 해결 방법을 찾았습니다.

내 환경은 electronwebpack 이지만 전자가 아닌 사람들에게도 도움이 될 수 있습니다. React 16.9(및 React DOM 16.9)로 업그레이드한 후 이 오류 메시지가 표시되는 이유를 해결하기 위해 고통스러운 날을 보냈습니다.

제 경우에는 앱에 두 개의 React가 있는 것 같았지만 npm ls react 사용하지 않고 node_modules에서 두 개의 물리적 라이브러리를 찾을 수 없었습니다. 번들 내부를 살펴보기 위해 webpack-bundle-analyzer 를 사용하기도 했습니다.

결국 프로젝트에 물리적으로 두 개의 반응이 없다는 것을 발견했지만 React와 React DOM은 HTML 파일에서 두 번 참조/로드되었습니다 . 이는 React 라이브러리의 index.js에 console.log("React load") 등을 추가하면 쉽게 확인할 수 있습니다.

실제 소스는 electron-webpack 에 연결되었습니다. react 및 react-dom은 외부로 표시되지 않았 으므로 다른 모듈에서 사용된 요구 사항으로 인해 나중에 node_modules에서 뿐만 아니라 번들에 로드되었습니다.

솔루션은 다음 행을 webpack.renderer.config.js 에 추가하는 것처럼 간단했습니다.

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

자, 여기 누군가가 parcel.js를 사용하는 경우 이상한 이유로 import React from 'React'; 가져오기를 수행할 수 있었습니다. 그리고 반응 후크를 사용하기 시작하면 인식하지 못하는 불변 위반 오류가 발생했습니다. from 'react' from 'React' 를 사용하여 부적절하게 가져오기 때문입니다. 이런.

당신 중 누구라도 같은 문제가 있었지만 개츠비와 관련이 있습니까?

'npm ls react' 후 다음과 같은 결과를 얻습니다.
image

및 'npm ls react-dom'
image

처음에는 실수로 react를 전역적으로 설치했다고 생각했는데 전역적으로 제거한 후 아무 것도 변경되지 않았습니다. 그런 다음 다른 디렉토리인 'gatsby new random-name'에 완전히 새로운 프로젝트를 만들고 작은 기능을 추가했습니다(https://www.youtube.com/watch?v=asrdFuAxPaU&feature=youtu에 따라 댓글 추가). .be)를 gatsby-starter-default에 추가하여 오류가 자체적으로 재현되는지 테스트합니다. 유감스럽게도, 그랬습니다!

어떤 조언이든 좌절한 평민들은 잘 받아들일 것입니다.

예, 귀하와 동일한 문제가 발생했습니다. 나는 여기의 조언을 따랐다 ... ,

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

페이지 아래 색인 파일에 React2를 추가했습니다. 거짓을 반환합니다.

중복 제거는 npm이 종속성을 중복 제거해야 함을 의미합니다 . 여기를 참조하세요...

같은 패키지를 두 번 설치할 필요가 없습니다! 참고만 한 것입니다.

또한 패키지를 "트리 위로"(트리를 평평하게) 이동합니다. 그렇지 않으면 하나의 패키지가 다른 패키지의 node_modules를 살펴봐야 하고(좀 지저분할 수 있음) 종속성을 단순화하는 데 도움이 되기 때문에 이것은 완전히 의미가 있습니다.

중복 제거라고 표시된 종속성 그래프의 모든 패키지는 일반적으로 "상위 수준"에서 그래프에서 한 번 이상 찾을 수 있으므로 이를 검증할 수 있습니다.

분명히 중복 제거가 작동하지 않았지만.

당신은 무엇을 시도 했습니까?

NextJS로 빌드하려고 할 때 이 오류가 발생합니다. 일부 구성 요소는 material-ui를 사용하며 제거하면 문제가 사라집니다. 나는 styled-component를 사용하지 않는다. 나는 운없이 node_modules 등을 삭제하려고했습니다. 내 next.config.js 파일과 package.json에서 행운 없이 react 에 대한 별칭을 추가하고 해결하려고 했습니다. 나는 react 16.8.6, react-dom 16.8.6 및 다음 9.0.4를 사용하고 있습니다. npm ls 는 각각 하나만 있다고 말합니다. npm 링크를 사용하지 않습니다.

저장소: https://github.com/dancancro/questions/tree/invalid-hook-call

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

스택 오버플로: https://stackoverflow.com/questions/57647040/nextjs-invalid-hook-call-hooks-can-only-be-call-inside-of-the-body-of-a-fun

오류는 다음과 같습니다. https://gist.github.com/dancancro/2dfafb053aaaedfade406fd4f67eb68a
... 렌더링 -> renderToString -> ReactDOMServerRenderer.read -> ReactDOMServerRenderer.render -> Object.WithStyles [렌더링으로] ...

문제가 되는 후크는 withStyles 함수에 있는 다음 파일의 17428행에 있는 useStyles() 호출입니다. "var classes = useStyles(props)"를 검색합니다. 문제는 nextjs 생성 코드에 있습니다. 내가 작성한 코드는 withStyles 또는 "use*"로 시작하는 후크 또는 기능을 사용하지 않습니다.

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

업데이트: next.config.js에서 이것을 제거하면 문제가 해결되었습니다.

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

연결된 패키지의 node_modules 폴더에서 reactreact-dom 을 삭제하여 해결 방법을 찾았습니다.

나는 많은 사람들과 같은 배를 타고 있습니다. 로컬에서 작업 중인 라이브러리 패키지가 있고 내 응용 프로그램 패키지의 변경 사항을 확인해야 할 때마다 게시하는 문제를 겪고 싶지 않습니다. 나는 그것을 연결하고이 오류가 발생하기 시작했습니다.

해결 방법은 다음과 같습니다.

  • 패키지 A: 라이브러리 코드 패키지가 npm link 되었습니다.
  • 패키지 B: 애플리케이션 코드 패키지. 패키지 A에 대한 node_modules 폴더에 심볼릭 링크가 있습니다.
  1. 빌드 패키지 A. Mine은 node_modules 를 포함하여 자산을 dist/ 로 출력합니다.
  2. 패키지 A의 배포된 node_modules 폴더에서 reactreact-dom 삭제
  3. ???
  4. 이익!

두 패키지에 동일한 버전의 React를 설치했습니다. 실행 중인 모든 프로세스를 다시 시작해야 합니다.

호환되지 않는 why-did-you-update 제거가 저에게 효과적입니다. (https://github.com/maicki/why-did-you-update/issues/52)

호환되지 않는 업데이트 이유

@bertho-zero 사용은 새로운 devtools 또는 내 후크 useWhyDidYouUpdate 를 사용할 수 있습니다.

@brunolemos 훌륭하지만 각 구성 요소에 넣어야 하기 때문에 더 제한적입니다.

@ dmart914 의 솔루션이 문제를 해결했습니다. 나도 변경 사항을 게시하지 않고 내 라이브러리를 테스트할 수 있도록 링크된 패키지가 있습니다... 누구든지 이에 대한 해결 방법을 찾았습니까? 오픈 소스 라이브러리를 게시하고 후크가 마술처럼 작동하기 시작하려면 특정 NPM 패키지를 삭제하는 것을 문서화해야 하는 것은 좋은 경험이 아닙니다...

연결된 패키지의 react 모듈을 제거하는 방법은 패키지에 react (예: @testing-library/react 또는 @testing-library/react-hooks )가 필요한 테스트가 있는 경우 작동하지 않으므로 이 문제를 처리할 더 나은 방법이 필요한 것 같습니다.

내 응용 프로그램은 두 부분으로 구성되어 있습니다. 메인 웹 애플리케이션과 웹 애플리케이션에 동적으로 로드되는 모듈. 웹 애플리케이션과 모듈 모두 React 16.9.0을 사용합니다.
모듈은 React.lazy() 및 동적 import() 문을 사용하여 웹 애플리케이션에 로드됩니다.
모듈이 로드되면 "잘못된 후크 호출" 오류가 발생합니다.

제 경우에는 기본 애플리케이션과 모듈이 별도로 구축되었기 때문에 서로를 인식하지 못하고 자체적인 반응 사본을 갖게 됩니다. 스레드에서 찾은 다음 제안을 시도했지만 문제가 해결되지 않았습니다.

  1. apieceofbart가 제안한 대로 메인 애플리케이션의 반응을 가리키는 모듈의 webpack.config에 별칭을 추가합니다.
    별칭: {
    반응: path.resolve('../../node_modules/react')
    }

  2. 모듈의 package.json에 있는 반응 종속성을 기본 애플리케이션으로 가리키려고 했습니다.
    "종속성": {
    "react-dom": " 파일:../common/node_modules/react-dom ",
    "반응": " 파일:../common/node_modules/react "
    }

반응은 동적으로 로드된 모듈과 관련하여 여러 복사본 실행을 지원해야 한다고 생각합니다.

위의 응답 중 일부를 기반으로 저에게 효과가 있었던 것은 다음과 같습니다.

  1. 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. package.json 수정됨
"devDependencies" : {
  ...
  "react": "^16.9.0",
  "react-dom": "^16.9.0",
}
"peerDependencies": {
  "react": "^16.9.0",
  "react-dom": "^16.9.0"
}
  1. 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>
...

그 후, 나는 CDN에서 로드된 React를 사용하여 내 라이브러리에서 후크를 실행할 수 있었고 Jest는 여전히 node_modules(devDependencies에서 설치)에서 반응 사본을 로드했습니다.

도움이 되기를 바랍니다.

내 구성 요소를 기능적 구성 요소에서 클래스 전체 구성 요소로 변경하려고 할 때 이 문제에 직면했고 이 오류도 발생하므로 이 오류에 대한 솔루션이 여기에 있습니다. 귀하의 경우에도 도움이 되기를 바랍니다.

이 경우 고차 구성 요소를 사용해보십시오.

'반응'에서 React 가져오기;
'prop-types'에서 PropType을 가져옵니다.
'@material-ui/styles'에서 { withStyles } 가져오기;
'@material-ui/core/Button'에서 버튼 가져오기;

const 스타일 = 테마 => ({
루트: {
배경: '선형 그라데이션(45deg, #FE6B8B 30%, #FF8E53 90%)',
테두리: 0,
테두리 반경: 3,
boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)',
색상: '흰색',
키: 48,
패딩: '0 30px',
},
});

클래스 HigherOrderComponent는 React.Component를 확장합니다. {

세우다(){
const { 클래스 } = this.props;
반품 (
고차 컴포넌트
);
}
}

HigherOrderComponent.propTypes = {
클래스: PropTypes.object.isRequired,
};

기본 내보내기 withStyles(styles)(HigherOrderComponent);

저는 Yarn을 사용하고 있으며 package.json 에서 강제로 해결 하여 이 문제를 해결했습니다.

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

상위 또는 하위 패키지에 추가했습니까?

위의 응답 중 일부를 기반으로 저에게 효과가 있었던 것은 다음과 같습니다.

  1. 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. package.json 수정됨
"devDependencies" : {
  ...
  "react": "^16.9.0",
  "react-dom": "^16.9.0",
}
"peerDependencies": {
  "react": "^16.9.0",
  "react-dom": "^16.9.0"
}
  1. 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>
...

그 후, 나는 CDN에서 로드된 React를 사용하여 내 라이브러리에서 후크를 실행할 수 있었고 Jest는 여전히 node_modules(devDependencies에서 설치)에서 반응 사본을 로드했습니다.

도움이 되기를 바랍니다.

실례가 되지는 않지만 이와 같은 해결책을 따라야 하는 것이 안타까울 뿐입니다. 나는 그런 해킹에 의존하지 않고 지난 며칠 동안 이 버그를 해결하려고 노력했습니다.

후크를 사용하는 구성 요소가 포함된 재사용 가능한 라이브러리에서 작업하고 있습니다. 게시하기 전에 실제 프로젝트에서 테스트해야 합니다. 이에 대한 유일한 해결책은 yarn|npm link 를 사용하는 것입니다. 롤업을 사용하여 라이브러리를 묶고 번들에 react 버전이 포함되어 있지 않은지 확인할 수 있습니다. 라이브러리를 사용하는 앱을 번들(웹팩)하면 버그/이슈가 나타납니다. 이것은 베어 create-react-appnext.js 앱에서도 발생합니다. 두 프레임워크 모두 백그라운드에서 웹팩을 사용합니다.

아직 지속 가능한 솔루션을 찾은 사람이 있습니까?

npm|yarn link 를 완전히 버리고 문제를 해결할 수 있었습니다. 대신 프로젝트 구조에 구애받지 않는 멋진 라이브러리를 사용합니다. 또한 webpack을 번들러로 계속 사용할 수 있으므로 _react_ 및 _react-dom_을 external 또는 alias 로 선언할 필요가 없습니다. 불행히도 프로젝트에 몇 가지 새로운 디렉토리와 잠금 파일을 도입하지만 로컬 및 도커 컨테이너 내부에서도 작동합니다.

아마도 이것은 목록에 약간 도움이 될 것입니다:

링크

@GabrielBB 감사합니다, 그것은 나를 위한 일입니다

@dmart914 감사합니다! 지금까지 나를 위해 작동하는 유일한 해결 방법 :)

현재 최소한의 간단한 설정을 사용할 때 React Invalid Hook Call 경고가 표시됩니다.

이 기능 구성 요소:

  1. React 및 ReactDOM에 동일한 버전을 사용합니다.
  2. Hooks의 규칙을 따릅니다.
  3. React 사본은 하나만 있습니다.

__종속성__
반응@16.10.1
[email protected]
웹팩@4.41.0
[email protected]

그리고 webpack test.js -o main.js 를 실행하여 빌드합니다.

이 파일이 다음을 수행할 것으로 예상합니다.

  • 상자를 렌더링합니다.

    • React.useState 를 호출하기 전에 디버거를 일시 중지합니다.

    • 부울 test 를 만들고 콜백 updateTest 을 업데이트합니다.

    • React 오류를 던집니다.

    • 렌더링 시 React.useEffect 콜백을 수행합니다.

    • React 오류를 던집니다.

제가 뭔가 잘못하고 있는 건가요, 아니면 다른 일이 벌어지고 있는 건가요?

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

실제로 요소를 만드는 것을 잊었습니다. ReactDOM.render 호출에 도달하기 전에 Item() 를 동기적으로 호출하고 있습니다. el(Item) 를 통과해야 합니다.

진실! 정보를 주셔서 감사합니다.

다른 댓글 작성자와 비슷한 상황입니다. 나는 webpack을 사용하여 일부 반응 구성 요소(일부는 후크를 사용함)를 변환하고 변환된 코드를 lib 폴더에 배치합니다. webpack 구성의 externals 필드에 반응을 추가하여 구성 요소 코드와 번들되지 않도록 했습니다. 이 구성 요소를 두 개의 개별 프로젝트에서 사용하고 싶습니다. 이러한 구성 요소는 둘 사이에 공통이므로 한 곳에서 개발하고 업데이트가 두 앱에 반영되도록 하고 싶습니다.

package.json에서 common-components: file:../../common-components/lib 를 사용하여 종속성을 추가하면 구성 요소가 완벽하게 로드되지만 webpack을 실행해도 구성 요소가 즉시 업데이트되지 않습니다. 대신 yarn upgrade common-components 를 실행한 다음 개발 서버를 다시 시작해야 합니다.

common-components: link:../../common-components/lib 를 사용하여 종속성을 추가한 경우 웹팩을 다시 실행하면 기본 앱의 node_modules 에 있는 파일이 업데이트되지만(지금은 심볼릭 링크를 사용하고 있기 때문에) 위의 오류가 발생합니다. 반응하다. 이제 common-components/node_modules 폴더에서 반응 버전을 사용하고 있다고 가정합니다.

연결된 구성 요소가 기본 앱의 node_modules 폴더에 있는 반응을 사용하는지 확인하면서 심볼릭 링크(예: common-components: link:../../common-components/lib )를 사용하는 방법이 있습니까? 두 앱 모두에서 이러한 구성 요소를 사용할 계획이므로 그 중 하나의 반응 패키지를 공통 구성 요소 라이브러리로 연결할 수 없으며 두 주요 앱의 반응을 공통 구성 요소 패키지에서 사용되는 반응에 연결하는 것을 피하고 싶습니다. 나는 웹팩 resolve 필드를 언급하는 몇 가지 의견을 보았지만 이 필드는 유망하게 들리지만 작동하게 할 수 없습니다. 어떤 도움이라도 대단히 감사하겠습니다!

편집: 우리의 사용 사례에 관심이 있는 사람을 위해 빌드 단계를 변경하여 파일이 필요한 두 프로젝트에 파일을 복사하고 완전히 변환하지 않도록 했습니다.

한 가지 빠른 해결 방법은 패키지를 게시하지 않고 github에 푸시하고 yarn add <git-url> 를 사용하여 프로젝트로 가져오는 것입니다.

한 가지 빠른 해결 방법은 패키지를 게시하지 않고 github에 푸시하고 yarn add <git-url> 를 사용하여 프로젝트로 가져오는 것입니다.

우리 중 많은 사람들이 npm 링크 및 npm 패키지 상대 경로를 사용하는 이유는 작동하는지 알기 전에 NPM 또는 GitHub에 변경 사항을 게시하지 않고도 코드를 개발하고 테스트하기 위해서입니다.

https://github.com/facebook/react/issues/13972#issuecomment -447599035 와 관련된 이 문제에 직면했습니다. Webpack'd Node 서버로 인해 발생할 수도 있다고 생각합니다. 우리의 사용 사례는 테스트를 실행하기 전에 서버를 구축하기 위해 프로그래밍 방식으로 webpack() 를 실행하는 Jest 내에서 실행되는 통합 테스트였습니다. 문제는 ESM과 CJS가 동시에 존재할 수 있는 방법과 관련이 있다고 생각합니다.

예를 들면 다음과 같습니다.

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

디버거 세션에서 내가 보고 있는 것은 이 파일의 컴파일된 버전에서 두 개의 서로 다른 React 인스턴스를 얻을 수 있다는 것입니다.

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

어디에
_react 는 이 파일의 ESM import React from 'react' 에서 가져왔습니다.
_react2node_modules/@apollo/react-ssr/lib/react-ssr.cjs.js 내에서 CJS var _react = _interopRequireDefault(require("react")); 입니다.

이로 인해 React에 대한 참조가 두 위치(서버 렌더링 파일 및 @apollo/react-ssr 번들 내부)에서 동일하지 않아 오류가 발생했다고 생각합니다.

우리는 이것이 아마도 테스트 내에서 webpack() 의 프로그래밍 방식 사용으로 인해 발생했음을 발견하고 해당 테스트를 종단 간 테스트로 리팩토링했습니다. 문제가 테스트 코드에서만 발생하는 경우 테스트가 지나치게 복잡할 수 있다는 교훈입니다.

원사로 해결했습니다.

myApp/node_modules/reactyarn link 로 cd

그런 다음 라이브러리에서 yarn link react 를 실행합니다.

이제 라이브러리가 기본 앱과 똑같은 반응 버전을 사용하고 있습니다.

내 라이브러리에서 피어 종속성으로 반응을 설정하려고 시도했지만 라이브러리가 빌드되지 않습니다.

$#$ yarn $#$ 을 꺼내거나 전환하지 않고 create-react-app 를 사용하여 이것을 어떻게 고칠 수 있습니까?

npm 링크를 사용하여 똑같은 기술을 사용할 수 있습니다. 배출이 필요하지 않습니다.

react 를 연결하는 것은 버전이 다른 여러 프로젝트에서 작업할 때 가장 좋은 아이디어가 아닙니다.

@woles 당신은 완전히 옳았지만 제 경우에는 내 '후크'문제를 해결합니다. 반응 개발자가 더 나은 솔루션을 제공하기를 바랍니다.

안녕,
반응 라우터 내부에서 실수로 구성 요소를 잘못 사용했다는 사실을 깨닫고 몇 시간 후에 이 버그를 수정했습니다.

내 앱이 작동했지만 한 구성 요소에서 useState를 전혀 추가할 수 없었습니다. 그 이유는 다음과 같은 고차 함수 없이 react routers render 메서드 내부의 구성 요소를 사용했기 때문입니다.
<Route exact path="/path" render={ ComponentCausingTheErrorMesage }/>
로 전환
<Route exact path="/path" component={ ComponentNowWorkingAgain }/>
나를 위해 그것을 고쳤다

앱과 현재 작업 중인 모듈 사이에 npm link 를 사용하고 있었는데 앱의 reactreact-dom 를 모듈에 연결한 다음 연결하여 수정해야 했습니다. 앱에 대한 모듈:

앱에서:

  1. cd node_modules/react && npm link
  2. react-dom 에 대해 동일

모듈에서:

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

앱에서:

  1. npm link [module-name]

이것이 누군가를 돕기를 바랍니다.

클라이언트 측에서 작동하는 후크가 있었지만 SSR에서 이 오류가 발생했습니다. 내 동료는 서버 측 웹팩 구성에서 다음을 사용하여 이 문제를 해결했습니다.

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

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

원사로 해결했습니다.

myApp/node_modules/reactyarn link 로 cd

그런 다음 라이브러리에서 yarn link react 를 실행합니다.

이제 라이브러리가 기본 앱과 똑같은 반응 버전을 사용하고 있습니다.

내 라이브러리에서 피어 종속성으로 반응을 설정하려고 시도했지만 라이브러리가 빌드되지 않습니다.

이것은 아름답게 작동합니다.

전자 웹팩을 사용할 때 반응과 재료 UI를 동시에 사용할 때 이 문제가 발생했습니다. material-ui에서 무엇이든 사용하려고 할 때 - 이 오류가 발생합니다(예:

안녕 ZVER3D, 내 이전 댓글 을 읽어보십시오. 도움이 되기를 바랍니다!

앱과 현재 작업 중인 모듈 사이에 npm link 를 사용하고 있었는데 앱의 reactreact-dom 를 모듈에 연결한 다음 연결하여 수정해야 했습니다. 앱에 대한 모듈:

앱에서:

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

2. same for `react-dom`

모듈에서:

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

2. `npm link`

앱에서:

1. `npm link [module-name]`

이것이 누군가를 돕기를 바랍니다.

귀여운 아기 모세, 이것은 저에게 많은 도움이되었습니다. 반응의 다른 버전이 문제라고 생각하지도 않았습니다!! NPM에 게시할 구성 요소를 로컬로 구축 중이지만 npm 링크를 사용하여 로컬에서 테스트할 별도의 프로젝트가 있습니다. 분명히 (지금) 그들은 서로 다른 버전의 반응을 사용하고 있습니다. 도!

안녕 ZVER3D, 내 이전 댓글 을 읽어보십시오. 도움이 되기를 바랍니다!

올바른 방향으로 안내해 주셔서 감사합니다. 또 다른 해결책은 "whiteListedModules"에 사용하는 ui 라이브러리를 추가하는 것입니다. 유일한 문제는 컴파일에 반응해야 하는 모든 모듈에 대해 이를 수행해야 한다는 것입니다.
그래서 package.json에서 다음과 같이 썼습니다.

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

monorepo 접근 방식을 사용하여 React 애플리케이션을 개발 중입니다. 메인 앱( brush )과 반응 라이브러리 구성 요소( react-gbajs )가 있습니다.

따라서 react-gbajs 구성 요소를 렌더링하려고 할 때 React의 여러 인스턴스에 대해 이 오류가 발생합니다. brush 에 동일한 코드를 복사하여 붙여넣으면 문제가 없습니다.
나는 그것을 고치기 위해 많은 접근 방식을 따랐지만 그들 중 누구도 그것을 해결하지 못했습니다(Webpack, Yarn의 작업 공간, npm 링크에서 빌드 변경...)

나는 정말로 두 개의 복사본이 있는지 확인하기 위해 디버그를 시도했지만 (React의 문서에서 console.log(window.React1 === window.React2) 사용) os React가 true 로 평가됩니다!
(지금 사용하고 있는 매우 나쁜 해결 방법은 후크를 소품으로 전달하는 것입니다: <GBAEmulator useEffect={useEffect} /> ... 하지만 실제로 병합하고 싶지는 않습니다)

누구든지 그것을 고칠 아이디어가 있습니까?

내 프로젝트는 오픈 소스이며 이 분기에 이 새로운 반응 라이브러리 구성 요소를 추가하고 있습니다 . -L274

안녕하세요 여러분,

사용자 지정 라이브러리(myDepPackage)를 종속성으로 사용하는 앱(myApp)이 있습니다. 둘 다 webpack 을 빌드 도구로 사용하고 있으며 물론 동일한 오류가 발생했습니다. 위의 솔루션 중 어느 것도 나를 위해 일하지 않았습니다. 그것이 한 일은 webpack이 사용자 정의 라이브러리(myDepPackage)의 최종 번들에 반응을 포함 하지 않도록 강제하는 것이었습니다. webpack 구성(myDepPackage의)에 추가해야 하는 유일한 구성 행은 다음과 같습니다.

externals: {
  react: "react",
},

https://webpack.js.org/configuration/externals/#externals 에서 "externals" 옵션에 대해 자세히 알아볼 수 있습니다.

@tsevdos Veeeery 감사합니다!!! ❤️
이전 의견에서 말한 내 문제를 해결했습니다.

우리에게 문제는 WordPress 단축 코드에서 페이지에 로드되고 임의의 ID로 div에 마운트되는 포함 가능한 React 앱이 있다는 것입니다. 일부 페이지에는 여러 개의 임베디드 앱이 있으며 후크를 사용하기 시작할 때까지 제대로 작동했습니다.

여러 임베디드 앱이 있는 페이지에서만 불평하므로 솔루션은 빌드와 함께 스크립트를 한 번만 로드하도록 WP 단축 코드를 업데이트하는 것이었습니다.

간단하고 분명한 것 같지만 알아내기가 어려웠습니다! 특히 우리가 후크를 추가할 때까지 그렇게 했고 잘 작동했기 때문입니다.

흥미롭게도 일부 페이지에는 후크를 사용하는 다른 - 다른 - 앱이 포함되어 있으며 React와 함께 자체 스크립트/빌드도 로드하지만... 그러면 제대로 작동합니다! 문제는 정확히 동일한 빌드가 두 번 이상 로드되고 후크를 사용하는 경우 였습니다.

저에게 효과가 있었던 것은 이 문제 스레드의 두 가지 제안을 조합한 것입니다.

메인 애플리케이션의 webpack 설정 ( @apieceofbart제안 )

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

종속성의 웹팩 구성( @tsevdos제안 )

  externals:
    react: 'react'
  }

html-webpack-plugin 에 이 문제가 있었고 index.htmltemplate 에서 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>

플러그인이 $ <div id="root"></div> <script type="text/javascript" src="main.js"></script> 를 주입하고 있다는 것을 깨달았습니다.

그래서 dev 도구를 열고 생성된 html은 다음과 같았습니다.

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

저에게는 Invalid Hook Call Warning 가 발생했습니다.

아래와 같이 <script src="main.js"></script> 를 제거하여 경고를 제거할 수 있었습니다.

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

</html>

솔루션을 찾는 사람에게 도움이 되길 바랍니다!

React 종속 라이브러리도 이러한 문제를 일으킬 수 있습니다. 제 경우에는 @emotion/core@emotion/styled 의 다른 버전을 사용하고 있었습니다.

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

안녕,

꺼내지 않고 가능한 솔루션은 웹팩 별칭 구성 솔루션을 사용자 정의 crareact-app-rewired 라이브러리와 혼합하는 것입니다. 이 방법을 사용하여 config-overrides.js 파일을 만들어 문제를 해결하는 데 필요한 웹팩 구성만 재정의할 수 있습니다.

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

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

Gatsby 사이트에서 이 문제가 발생했습니다. npm install을 실행하고 최신 버전의 Gatsby로 업데이트했더니 모두 해결되었습니다.

yarn or npm test (저처럼)를 실행하는 농담 테스트에 문제가 있고 react-test-renderer 를 사용하는 경우 react-test-rendererreact 의 동일한 버전과 일치하는지 확인하십시오. 당신은 사용하고 있습니다.

예시:

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

yarn add [email protected] 실행

나는 lib가 있고 lib와 기본 프로젝트 모두에서 reactreact-dom 의 모든 버전을 확인했습니다. 그들은 정확히 동일하지만 작동하지 않았습니다.
그러나 @pieceofbart 솔루션이 저에게 효과적이었습니다.

@apieceofbart , 당신은 나의 하루를 구했습니다 <3

저에게 효과가 있었던 것은 이 문제 스레드의 두 가지 제안을 조합한 것입니다.

메인 애플리케이션의 webpack 설정 ( @apieceofbart제안 )

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

종속성의 웹팩 구성( @tsevdos제안 )

  externals:
    react: 'react'
  }

여기도 마찬가지입니다. 작동하려면 이 두 가지 수정 작업을 모두 수행해야 합니다. 내 설명은 두 번째 구성이 'react'라는 이름으로 외부 반응을 사용하도록 종속성을 알리고 첫 번째 구성이 'react'라는 이름을 주 저장소의 'node_modules/react' 폴더로 가리킵니다. 따라서 반응 브리지가 작동하려면 둘 다 필요합니다.

그래도 어떤 사람들에게는 그 중 하나로 충분할 것 같습니다. 나는 정말로 이해하지 못합니다.

저에게 효과가 있었던 것은 이 문제 스레드의 두 가지 제안을 조합한 것입니다.
메인 애플리케이션의 webpack 설정 ( @apieceofbart제안 )

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

종속성의 웹팩 구성( @tsevdos제안 )

  externals:
    react: 'react'
  }

여기도 마찬가지입니다. 작동하려면 이 두 가지 수정 작업을 모두 수행해야 합니다. 내 설명은 두 번째 구성이 'react'라는 이름으로 외부 반응을 사용하도록 종속성을 알리고 첫 번째 구성이 'react'라는 이름을 주 저장소의 'node_modules/react' 폴더로 가리킵니다. 따라서 반응 브리지가 작동하려면 둘 다 필요합니다.

그래도 어떤 사람들에게는 그 중 하나로 충분할 것 같습니다. 나는 정말로 이해하지 못합니다.

두 번째 항목이 중요합니다!
무시하면 빌드 프로세스에서 내부 종속성이므로 반응이 함께 내보내집니다.

@apieceofbart 많이 사랑해주세요!!!! 내 책상을 벽으로 걷어차려 할 뻔했어

따라서 마이크로 서비스에 대한 해결 방법은 아직 없습니다. 다른 반응과의 번들을 동적으로 요구하는 반응이 있는 루트 응용 프로그램이 있습니다. 자체 의존성을 가진 많은 독립적인 팀이 있기 때문에 우리는 react의 외부 버전을 사용할 수 없습니다. 동일한 외부 버전을 사용하도록 강요하면 대부분의 프로젝트가 분명히 충돌하고 각 프로젝트가 이 버전에 의존하기 때문에 이 버전을 업그레이드하는 것이 불가능해집니다.

어떤 아이디어?

CRA에서 꺼내지 않아도 되는 반응 후크를 npm 링크와 함께 사용하는 솔루션이 있습니까?

@tschellenbach
craco를 사용하여 꺼내지 않고 CRA 구성을 덮어쓸 수 있습니다.
https://github.com/gsoft-inc/craco

@tsevdos 덕분에 내 문제를 해결하고 React 패키지를 만드는 방법에 대한 자습서를 만들었습니다. https://youtu.be/esyS87NfBOw

나는이 문제가 발생했고 대신 소포 번들러를 사용하고 있기 때문에 webpack 솔루션이 적용되지 않았습니다. 다음과 같은 내 메인 앱의 package.json에 별칭을 지정하여 문제를 해결할 수 있었습니다.

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

다른 패키지 json이 있는 동일한 프로젝트의 전자 앱에서 내 React 구성 요소(훅으로 작성됨)를 사용하려고 할 때 문제가 발생합니다. 파일 구조는 다음과 같습니다.

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

두 package.json 모두 package.json에 react 및 react-dom을 포함하지만 동일한 버전이며 npm ls react 할 때 두 개의 반응 설치가 표시되지 않습니다. 어떤 아이디어?

편집: @ewan-m의 솔루션이 작동했습니다!

그래서 이상한 케이스에 빠진 것 같아요. 타사 라이브러리에는 불행히도 기능 및 클래스 기반 구성 요소가 혼합되어 있습니다. 내 코드베이스의 구성 요소가 작동합니다. 라이브러리의 클래스 기반 구성 요소는 내 구성 요소를 자식으로 렌더링하는 레이아웃 역할을 합니다. 이것이 '오류: 잘못된 후크 호출'을 유발하는 원인이라고 생각합니다. 후크를 사용하려면 이 문제를 어떻게 해결해야 합니까? 내 것을 클래스 구성 요소로 변환해야 합니까?

@GrandathePanda 믹싱 클래스와 기능적 구성 요소는 중요하지 않아야 합니다. 클래스가 후크를 호출하는 함수를 호출하면 거기에는 문제가 없습니다. 할 수 없는 유일한 것은 클래스에서 직접 후크를 호출하는 것입니다.

좋아, @JeremyGrieshop 그러면 아직 조사해야 할 부분이 있습니다. 타사 구성 요소를 사용하지 않고 렌더링하면 제대로 렌더링되므로 해당 라이브러리와 코드 간에 충돌이 발생합니다. 그들이 다른 반응 버전을 사용하고 있다고 추측해야한다면 아마도 패키지에있을 것입니다.

좋아, @JeremyGrieshop 그러면 아직 조사해야 할 부분이 있습니다. 타사 구성 요소를 사용하지 않고 렌더링하면 제대로 렌더링되므로 해당 라이브러리와 코드 간에 충돌이 발생합니다. 그들이 다른 반응 버전을 사용하고 있다고 추측해야한다면 아마도 패키지에있을 것입니다.

맞습니다. 앱에서 npm ls react react-dom 를 확인하여 여러 버전이 있는지 확인하세요. 타사 라이브러리에 특정 버전에 대한 종속성이 있을 수 있습니다.

@JeremyGrieshop 따라서 내 응용 프로그램은 반응 및 dom에 16.12.0을 사용하고 타사(elastic search-ui)는 반응 및 dom에 16.8.0을 사용하는 것 같습니다. 내가 맞다면 문제는 16.8.0 타사 라이브러리가 16.12.0으로 생성된 구성 요소를 렌더링하기 때문에 문제가 발생한다는 것입니다. 그들은 또한 위의 모든 주석을 읽은 후에 잠재적으로 이것을 더 복잡하게 만드는 lerna monorepo입니다. 이 문제는 materialui에서 생성된 useStyles 후크에서 발생하며 이전 버전과의 호환성을 위해 withStyles hoc을 제공하며 그 동안에는 그 경로로 갈 것이라고 생각합니다. 위에서 언급한 webpack 및/또는 패키지 json에 대한 모든 변경 사항은 후크가 다양한 구현 문제에 직면하여 성숙하는 방법을 알아내는 동안 그 동안 고전적인 임시로 가는 것보다 깨지기 쉬운 반창고처럼 보입니다.

@GrandathePanda IMHO, 귀하의 옵션은 (1) 제3자가 반응 종속성을 16.12로 업데이트하거나 peerDependency로 사용하는 것이 종속성보다 더 적합한지 결정하도록 하는 것입니다. (2) 앱에서 16.8을 사용하여 동일한 lib 버전을 공유합니다. (3) 다음을 사용하여 반응 사본을 제거합니다.

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

위의 명령은 package.json의 "스크립트" 부분 아래에 있는 "사전 빌드" 및 "사전 시작"에 배치할 수 있습니다(현재 하고 있는 작업입니다). (3)의 단점은 다음과 같습니다. 16.8과 16.12 사이에서 더 이상 사용되지 않는 것을 사용하고 있습니다.

안녕하세요 여러분,

사용자 지정 라이브러리(myDepPackage)를 종속성으로 사용하는 앱(myApp)이 있습니다. 둘 다 webpack 을 빌드 도구로 사용하고 있으며 물론 동일한 오류가 발생했습니다. 위의 솔루션 중 어느 것도 나를 위해 일하지 않았습니다. 그것이 한 일은 webpack이 사용자 정의 라이브러리(myDepPackage)의 최종 번들에 반응을 포함 하지 않도록 강제하는 것이었습니다. webpack 구성(myDepPackage의)에 추가해야 하는 유일한 구성 행은 다음과 같습니다.

externals: {
  react: "react",
},

https://webpack.js.org/configuration/externals/#externals 에서 "externals" 옵션에 대해 자세히 알아볼 수 있습니다.

@tsevdos 사랑해요. 당신은 격렬한 번거 로움의 며칠을 끝냈습니다. 감사합니다.

안녕하세요 여러분,

구성 요소에서 후크를 사용하려고 합니다. 이 구성 요소는 gatsby-browser.js 에서 내보내야 합니다.

현재 행동은 무엇입니까?

이 오류가 발생합니다.

처리되지 않은 거부(오류): 잘못된 후크 호출입니다. 후크는 함수 구성 요소의 본문 내부에서만 호출할 수 있습니다. 다음 이유 중 하나로 인해 발생할 수 있습니다.

  1. React와 렌더러(예: React DOM)의 버전이 일치하지 않을 수 있습니다.
  2. Hooks의 규칙을 어길 수 있습니다.
  3. 동일한 앱에 둘 이상의 React 사본이 있을 수 있습니다.
    이 문제를 디버그하고 수정하는 방법에 대한 팁은 https://fb.me/react-invalid-hook-call 을 참조하십시오.

다음은 샘플 코드입니다.

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;

예상되는 동작은 무엇입니까?

Hook은 오류 없이 실행되거나 유용한 오류 메시지가 제공되어야 합니다.

react 및 react-dom 종속성의 버전은 16.12.0입니다.

@leejh3224 정말 고마워요! 몇 시간 동안 검색 한 후이 답변을 찾았습니다. 내 문제가 해결되었습니다.
HtmlWebpackPlugin 구성을 다음에서 변경했습니다.
inject: true 에서 inject: 'head' 로 변경되고 축소된 반응 오류가 사라졌습니다.

나는 이것을 작동시키려고 노력한 경험으로 stackoverflow 질문 을 만들었습니다. 이 작업을 수행한 사람들이 살펴보고 조언을 제공하는 것이 가능합니까?

jquery 애플리케이션을 React로 이식 중입니다. asJqueryPlugin 라는 jQuery 내에서 React 구성 요소를 노출하는 유틸리티가 있습니다. 파일은 다음과 같습니다.

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

이 앱은 Webpack에 많은 진입점이 있으며 현재 약 3-4개의 구성 요소가 이 기술을 사용하고 있습니다. 구성 요소가 다른 진입점 번들로 번들될 때 문제가 발생한다고 생각합니다.

따라서 Webpack에 두 개의 진입점이 있는 경우:

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

그런 다음 각 파일에서 노출된 구성 요소(각각 후크 사용)를 설정합니다.

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

이제 동일한 페이지에 두 항목을 모두 포함하고 jquery 플러그인을 통해 두 구성 요소를 모두 렌더링하려고 하면...

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

...이 후크 오류가 발생합니다.

이것이 대화에 도움이 되는지 여부는 확실하지 않지만 적어도 (의심스럽게도) 제정신인 개발자가 여러 반응 인스턴스가 있는 상황에 어떻게 대처할 수 있는지에 대한 사용 사례를 보여줍니다.

그게 저를 도왔습니다 - https://github.com/facebook/react/issues/13991#issuecomment -554928373
그러나 또한 종속성에서 reactreact-dom 를 제거하고 피어 종속성으로 이동하고 노드 모듈을 제거했다가 다시 설치해야 했습니다.

안녕,
웹에서 대화와 많은 게시물을 읽었지만 여전히 반응의 여러 인스턴스에 오류가 있습니다.
버그 재현을 위해 이 리포지토리를 푸시합니다. https://github.com/jeromelegrand/dooliz-lib
누군가가 나를 도울 수 있기를 바랍니다.
감사 해요.

이 문제에 직면하고 있으며 위의 솔루션으로 아무데도 얻을 수 없습니다.
간단히 말해서: 나는 하나의 반응 버전만 실행하고 있다고 확신하고 반응 부트스트랩을 사용하여 오류가 발생합니다. 다른 사람에게는 문제가 없기 때문에 후크를 잘못 사용하지 않을 것입니다.

이 오류는 node.js 백엔드에서 발생합니다.

__반응 버전에서 내가 확인한 것__

작업 공간이 있는 원사 설정이 있는데 yarn list react 또는 yarn list react-dom 는 하나의 인스턴스만 표시합니다.

가져온 항목을 보려면 캐시 필요를 인쇄했습니다.

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

나는 잘못된 후크 오류를 일으키는 react-bootstrap에서 무언가를 렌더링하기 직전에 실행하고 다음을 기록합니다.

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

1개의 반응 버전만 로드되었음을 확인하는 것 같습니다.

마지막으로 이것을 node_modules/react-dom/index.js에 추가했습니다.

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

그리고 이것은 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'));

SAME 인쇄

이것이 또 무엇일 수 있습니까?
나는 또한 이것을 react-bootstrap repo에 게시할 것입니다.

따라서 두 개의 React 인스턴스를 갖는 것이 여기서 문제가 아니라고 확신합니다. 나는 문제가 두 개의 반응 _roots_가 있을 때라고 생각합니다. 페이지의 다른 부분으로 ReactDOM.render() 를 여러 번 호출하고 있습니까? 그렇다면 이것이 문제를 일으킬 수 있다고 생각합니다. 나는 후크가 특정 "루트"에 "속한다"고 생각하고 후크가 여러 개 있고 두 번들이 몇 가지 공통 코드를 공유할 때 중단됩니다. 여기 있을 것 같은데...

... 문제는 두 개의 반응 _roots_가 있을 때라고 생각합니다. 페이지의 다른 부분으로 ReactDOM.render() 를 여러 번 호출하고 있습니까?

@timkindberg 감사합니다. 덕분에 문제를 해결할 수 있었습니다. ReactDOMServer.renderToString 로 최종 렌더링을 하기 전에 react-tree-walker 를 사용하여 초기 렌더링을 수행하고 필요한 데이터를 가져오고 있음을 깨달았습니다.

이 패키지의 사용을 빠르게 제거하면 오류가 제거되었으며 이제 react-ssr-prepass 와 동일한 작업을 수행할 수 있습니다. 이는 이제 react-tree-walker readme 페이지에서 실제로 권장됩니다.

그래서 실제로 두 번의 ReactDOM.render 호출이었습니다! 지금은 react-ssr-prepass 를 사용하는 이 설정이 저에게 효과적이며 Suspense가 react-dom/server에 도착하면 해당 설정으로 전환할 수 있습니다.

내 Gutenberg 프로젝트에서 react-compare-image https://github.com/junkboy0315/react-compare-image 를 사용하고 있지만 저장 기능에서 ReactCompareImage 구성 요소를 제거할 때마다 모든 것이 작동하지만 이 이상한 문제가 있습니다. 편집 기능은 완벽하게 작동하지만 저장이 작동하지 않습니다.

나는 https://reactjs.org/warnings/invalid-hook-call-warning.html 을 보았고 나는 이러한 문제가 있다고 생각하지 않습니다.

다음은 완전한 저장 기능 파일입니다.

```"./inspector"에서 Inspector 가져오기;
"반응"에서 { 조각 } 가져오기;
"react-compare-image"에서 ReactCompareImage 가져오기;

/**

  • 워드프레스 종속성
    */
    상수 {__} = wp.i18n;

const 저장 = ({클래스 이름, 속성}) => {

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

};

기본 저장 내보내기;
```
Screenshot 2020-02-19 at 4 11 52 PM

나는 또한이 문제에 직면 해 있습니다. 나는 SO 에 요약을 게시했습니다.

나는 또한 최소한의 재현 가능한 예가 있습니다: https://github.com/coler-j/shopify_playground

내 메인 앱은 React도 사용하는 공유 라이브러리를 가져오는 create-react 앱(꺼내지 않음)입니다. 나는 이것을 다음과 같이 해결할 수 있었다.

웹팩 대신 롤업을 사용하여 라이브러리 패키지하기
어떤 이유에서인지 아직 해결하지 못했기 때문에 외부를 사용해도 라이브러리 번들에서 React가 제거되지 않았습니다.

롤업 구성.js

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

craco를 설치하고 이를 사용하여 메인 앱의 웹팩 수정
craco.config.js

const path = require('path')

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

craco를 알려준 @arminyahya 에게 감사드립니다.

cdn에서 반응을 로드하는 동안 후크를 사용하려고 합니다. 이 예제(전체 html 페이지)는 Example() Hooks can only be called inside of the body of a function component 오류를 제공합니다. ReactDOM까지 모두 제거했으므로 React의 여러 복사본을 가질 수 있다고 상상하기 어렵습니다. 이게 그냥 불가능한 건가요?

<!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 반응 루트가 제로이기 때문입니다. 애플리케이션을 렌더링해야 합니다. 그러나 이것은 후크가 반응 루트에 의존하고 연결된다는 좋은 확인입니다.

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

감사합니다! 실제로는 반응 루트가 없는 것이 아닙니다. 오류를 최대한 단순화하는 과정에서 제거했습니다. 하지만 똑같이 멍청한 것입니다. <Example /> Example() 를 썼습니다.

아무것도 나를 위해 작동하지 않는 것 같습니다. 다른 프로젝트에서 공유하고 사용할 구성 요소를 만들고 있는데 다른 프로젝트에서 로컬로 테스트할 때 작동하지 않습니다. 나는 반응 16.13.0과 함께 Hooks를 사용하고 있습니다.

웹팩.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',
    }),
  ]}

어떤 제안? 나는 오래된 토론의 모든 제안을 테스트했습니다.
감사 해요! :이를 드러내고 웃다:

다음과 같이 Settings.js를 선언했습니다.

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

다음과 같이 App.js에서 가져와서 사용합니다.

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

그러나 나는 얻는다:

Screenshot 2020-02-27 at 22 27 01

나는 사용하고 있습니다 :

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

뭐가 문제 야?

Settings 구성 요소를 함수 구성 요소가 아닌 함수로 호출하고 있습니다.

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

후크는 일반 함수 내에서 허용되지 않으며 함수 구성 요소에서만 허용되며 호출하는 방식은 React가 구성 요소가 실제로는 정상적인 기능이라고 생각하도록 속입니다.

아마도 이것은 누군가에게 두통을 덜어줄 것입니다. 만약 당신이 이와 같이(적절한 방법이 아닌) 렌더에서 컴포넌트를 전달한다면 react-router-dom을 사용한다면 Invalid Hook Call Warning 를 줄 것입니다.
<Route path="/:cuid/:title" render={PostArticle} />

내가 어디에서 잘못되었는지 알기 위해 30분이 걸렸어

이것은 누군가에게 도움이 될 수 있습니다. react-router-dom을 사용한 후 이 버그가 발생했다면 경로를 어떻게 정의했는지 확인하세요. 예를 들어 $ <Route path={'/upgrade/:plan'} exact children={Upgrade} /> #$를 하는 동안 <Route path={'/upgrade/:plan'} exact children={<Upgrade />} /> 이어야 합니다.

잉크파스텔 을 사용하여 CLI를 구축하는 경우 특히 어색합니다(https://github.com/vadimdemedes/pastel/issues/2 참조). 모든 사용자에게 React를 설치하도록 요청할 수 없고 특정 버전/범위의 React를 사용하도록 강제할 수도 없기 때문에 PeerDep으로 만들 수 없습니다.

우리 팀은 Yarn을 사용하고 있으며 앱이 아닌 테스트에서만 Invalid hook call 오류가 발생했습니다. 문제는 react-test-rendererreactreact-dom 보다 낮은 버전으로 해석되어 package.json resolutions 를 추가했다는 것입니다.

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

하위 디렉토리에서 Gatsby를 사용하는 사람들에게는 이것이 가능한 솔루션입니다.

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

npm link 명령을 실행할 때도 동일한 문제가 있습니다. 문제가 있습니다.

그런 다음이 문제를 해결하기 위해 react에서 제공하는 공식 솔루션을 사용했습니다.

이 문제는 npm 링크 또는 이에 상응하는 것을 사용할 때도 발생할 수 있습니다. 이 경우 번들러는 두 개의 Reacts를 "볼" 수 있습니다. 하나는 애플리케이션 폴더에 있고 다른 하나는 라이브러리 폴더에 있습니다. myapp과 mylib가 형제 폴더라고 가정하면 가능한 수정 사항 중 하나는 mylib에서 npm link ../myapp/node_modules/react를 실행하는 것입니다. 이렇게 하면 라이브러리가 애플리케이션의 React 복사본을 사용하게 됩니다.

A가 B를 소개해야 하는 경우 (A와 B는 형제입니다)

  • 1단계(B에서)

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

    • npm link

  • 2단계(A)
    npm link B

그것은 나를 위해 작동합니다

이러한 답변에도 불구하고 오류가 발생하는 이유가 확실하지 않습니다. 내 종속성 라이브러리가 내 기본 앱에 연결되어 있고 오류가 발생한 후 react-docs를 따라 내 종속성 라이브러리 버전을 내 앱의 반응에 연결했습니다( npm link <>/webapp/node_modules/react 실행). dom). React1과 React2가 같은지 테스트하기 위해 로그인했을 때 true 로 기록되어 중복 버전의 React를 사용하지 않고 동일한 버전의 React를 사용하고 있었고 함수 구성 요소를 사용하고 있었습니다. 따라서 테스트 로깅에 React의 중복 버전이 없다고 표시되었지만 여전히 후크 오류가 발생했습니다.

그러나 위에서 언급한 대로 이 솔루션을 시도하면 특정 버그가 수정되었습니다.

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

그래서 나는 길을 잃었다.

그래서 나는 길을 잃었다.

@orpheus 동일한 페이지에 하나 이상의 반응 루트를 렌더링합니까? 같은 페이지에 ReactDOM.render 호출이 두 개 이상 있습니까?

동일한 페이지에 하나 이상의 반응 루트를 렌더링합니까? 같은 페이지에 ReactDOM.render 호출이 두 개 이상 있습니까?

@팀킨드버그

나는 아니에요. 내 app 의 루트에 하나의 ReactDOM.render 가 있고 연결하는 lib 모듈은 구성 요소 라이브러리이며 ReactDOM.render 를 사용하지 않습니다. 조금도.

편집 : 나는 비슷한 일을하고 있습니다 :

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

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

여기서 <Root /> 는 다음과 같은 것을 렌더링합니다.

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

PermissionsProvider 는 연결된 lib 모듈에서 가져오는 React 구성 요소로, 앱을 실패하게 만드는 후크를 사용합니다. 상태와 컨텍스트를 생성하고 자식을 렌더링합니다.

안녕하세요, 나는 반응 후크와 함께 전자를 사용하고 있습니다. 내 자신의 후크를 작성하면 작동합니다. 하지만 react-use , swr 와 같이 node_module의 다른 패키지에서 후크를 사용하면 오류가 발생합니다.

패키지를 로컬 파일에 복사해야 합니다.

누구든지이 문제를 해결합니까?

여기 예시 프로젝트:
https://github.com/Zaynex/electron-react-ts-kit/tree/hooks-error

핵심 코드:
https://github.com/Zaynex/electron-react-ts-kit/blob/hooks-error/src/renderer/app.tsx

react 및 react-dom의 중복 복사본을 제거한 후에도 이 문제가 계속 발생합니다. 재현할 수 있는 매우 간단한 테스트 프로젝트 를 만들었습니다.

$ 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

현재 webpack 별칭 방법을 사용하고 있지만 npm link 방법도 시도했지만 둘 다 작동하지 않습니다.

이 문제도 발견했습니다. 저는 ExpressJS + Pug를 사용하여 뷰를 렌더링하고 있습니다. 그런 다음 구성 요소 서버 및 클라이언트 측을 렌더링할 수 있는 렌더러(ReactRails와 유사)를 작성했습니다.

지저분해져서 별도의 패키지로 압축을 풀려고 했더니 이 문제가 발생했습니다.

이 문제를 해결하기 위해 resolve 키 아래에 다음을 추가해야 했습니다.

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

이제 webpack을 정상적으로 실행할 때 예상대로 작동하지만 문제는 여전히 도커 볼륨에서 지속됩니다. 나는 docker를 다루기에는 너무 초보이므로 나중에 다시 방문할 예정입니다.

편집: 내가 너무 빨리 말했다. 이제 React render에서는 잘 작동하지만 hydrate에서는 작동하지 않습니다.

안녕하세요, 나는 반응 후크와 함께 전자를 사용하고 있습니다. 내 자신의 후크를 작성하면 작동합니다. 하지만 react-use , swr 와 같이 node_module의 다른 패키지에서 후크를 사용하면 오류가 발생합니다.

패키지를 로컬 파일에 복사해야 합니다.

누구든지이 문제를 해결합니까?

여기 예시 프로젝트:
https://github.com/Zaynex/electron-react-ts-kit/tree/hooks-error

핵심 코드:
https://github.com/Zaynex/electron-react-ts-kit/blob/hooks-error/src/renderer/app.tsx

여보세요. 나는 같은 문제가 있었다. 모든 모듈을 웹팩의 외부로 표시하는 전자 웹팩을 사용하고 있습니다. react 및 react-dom과 같은 하드 코딩된 예외가 거의 없습니다.
나에게 그것은 내 코드에서 로드된 반응이 그러한 모듈에서 로드된 반응과 다르다는 것을 의미했습니다.
이러한 모듈을 화이트리스트 에 추가하는 것이 도움이 되는 것 같습니다(아직 다른 것이 손상되지 않았는지 확실하지 않습니다.)

@huh 감사합니다, 작동합니다! 우리는 전자 웹팩에 뛰어들어야 합니다.

나는 이것을 스스로 작동하게했습니다. Lerna 및 Yarn 작업 공간과 관련하여 더 나은 솔루션 중 하나라고 생각하며 일부 조각을 다른 솔루션에 사용할 수 있습니다.

모든 것이 내가 가져오는 package.json 프로젝트의 구성으로 요약되는 것 같습니다. 다음 섹션을 포함해야 했습니다.

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

이 작업을 수행한 후 프로젝트를 다시 빌드해야 했고 정상 실행되었습니다. 피어 종속성으로 나열하면 소비 프로젝트에서 설치해야 할 수 있습니다. 그리고 그것들은 의존성에 나열되어 있지 않기 때문에 가져오려는 패키지에서 사용할 수 없어야 합니다. 하지만 어떤 이유로 호이스트하지 않도록 지시하지 않는 한 계속 사용할 수 있고 새로운 반응 인스턴스가 들어오고 오류가 발생합니다.

행운을 빕니다!

간단한 페이드 인 효과를 얻기 위해 react-spring을 사용하려고 합니다. 아무것도 작동하지 않는 것 같습니다.
`'react'에서 React, { useState, useEffect } 가져오기;
'react-spring'에서 {애니메이션, useTransition} 가져오기;

const TextContent = (소품) => {

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

}

기본 TextContent 내보내기;`
Capture

React의 인스턴스가 여러 개 있는지 확인하려고 했습니다. Npm ls-ing은 내가 16.13.1에 있는 react 및 react-dom의 단일 버전만 가지고 있다고 알려줍니다.

안녕하세요, 나는 반응 후크와 함께 전자를 사용하고 있습니다. 내 자신의 후크를 작성하면 작동합니다. 하지만 react-use , swr 와 같이 node_module의 다른 패키지에서 후크를 사용하면 오류가 발생합니다.
패키지를 로컬 파일에 복사해야 합니다.
누구든지이 문제를 해결합니까?
여기 예시 프로젝트:
https://github.com/Zaynex/electron-react-ts-kit/tree/hooks-error
핵심 코드:
https://github.com/Zaynex/electron-react-ts-kit/blob/hooks-error/src/renderer/app.tsx

여보세요. 나는 같은 문제가 있었다. 모든 모듈을 웹팩의 외부로 표시하는 전자 웹팩을 사용하고 있습니다. react 및 react-dom과 같은 하드 코딩된 예외가 거의 없습니다.
나에게 그것은 내 코드에서 로드된 반응이 그러한 모듈에서 로드된 반응과 다르다는 것을 의미했습니다.
이러한 모듈을 화이트리스트 에 추가하는 것이 도움이 되는 것 같습니다(아직 다른 것이 손상되지 않았는지 확실하지 않습니다.)

멋진! 감사합니다

간단한 페이드 인 효과를 얻기 위해 react-spring을 사용하려고 합니다. 아무것도 작동하지 않는 것 같습니다.
`'react'에서 React, { useState, useEffect } 가져오기;
'react-spring'에서 {애니메이션, useTransition} 가져오기;

const TextContent = (소품) => {

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

}

기본 TextContent 내보내기;`
Capture

React의 인스턴스가 여러 개 있는지 확인하려고 했습니다. Npm ls-ing은 내가 16.13.1에 있는 react 및 react-dom의 단일 버전만 가지고 있다고 알려줍니다.

여기도 마찬가지입니다. react 및 react-dom은 16.13.1에 있으며 react-spring을 사용하려고 하면 동일한 오류가 발생합니다.

styled-components package.json file: URI를 통해 자체 로컬 패키지를 사용하는 경우 rm -rf node_modules/local-package-name/node_modules 중복 종속성을 확인하지 않고 로컬 패키지를 복사하기 때문에 앱을 실행하기 전에 node_modules .

styled-components package.json file: URI를 통해 자체 로컬 패키지를 사용하는 경우 rm -rf node_modules/local-package-name/node_modules 중복 종속성을 확인하지 않고 로컬 패키지를 복사하기 때문에 앱을 실행하기 전에 node_modules .

예, 이것은 이 스레드에서만 대략 12가지 사용 사례에 대한 동일한 문제입니다. rm -rf(rimraf 사용)를 수행하기 위해 "사전 시작" 및 "사전 빌드" 대상을 추가했습니다. 이 스레드의 다른 사용자는 사전 시작에서 npm-link-shared를 사용하여 모듈이 동일한 반응 인스턴스를 공유하도록 했습니다. 우리 중 많은 모노레포 사용자가 이 문제를 겪고 있습니다.

안녕하세요, 나는 반응 후크와 함께 전자를 사용하고 있습니다. 내 자신의 후크를 작성하면 작동합니다. 하지만 react-use , swr 와 같이 node_module의 다른 패키지에서 후크를 사용하면 오류가 발생합니다.
패키지를 로컬 파일에 복사해야 합니다.
누구든지이 문제를 해결합니까?
여기 예시 프로젝트:
https://github.com/Zaynex/electron-react-ts-kit/tree/hooks-error
핵심 코드:
https://github.com/Zaynex/electron-react-ts-kit/blob/hooks-error/src/renderer/app.tsx

여보세요. 나는 같은 문제가 있었다. 모든 모듈을 웹팩의 외부로 표시하는 전자 웹팩을 사용하고 있습니다. react 및 react-dom과 같은 하드 코딩된 예외가 거의 없습니다.
나에게 그것은 내 코드에서 로드된 반응이 그러한 모듈에서 로드된 반응과 다르다는 것을 의미했습니다.
이러한 모듈을 화이트리스트 에 추가하는 것이 도움이 되는 것 같습니다(아직 다른 것이 손상되지 않았는지 확실하지 않습니다.)

이것은 redux 또는 redux 툴킷과 electron-webpack에 문제가 있는 사람들에게도 적용됩니다. 다음 작업 구성이 있습니다.

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

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

내 문제는 내가 썼다

import React from 'React'

대신에:

import React from 'react'

때로는 어리석은 일입니다.

웹팩 구성에 다음을 추가하여 문제를 해결했습니다.

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

처음에는 npm 링크의 문제라고 생각했고 제안된 모든 작업을 수행했으며 심지어 원사로 전환했습니다. 결국 다른 프로젝트에서 가져올 때 npm에 게시할 때 동일한 오류가 발생했을 때 다른 일이 일어나고 있다고 생각했습니다.

최근에 lerna monorepo로 이 문제를 해결한 사람이 있습니까? 나는 운이 없이 몇 가지 제안을 시도했습니다.

아래 //로 주석 처리된 코드를 추가한 후 오류가 발생했습니다. CssBaseline을 추가하고 조각 정보를 반응하면 오류가 발생합니다. 주석 처리되면 모든 것이 잘 실행됩니다. 원본 코드는 단순히 기본 npx create-react-app 코드입니다. 이것은 완전히 새롭고 위에서 시도한 몇 가지 수정 사항은 효과가 없었습니다.

'반응'에서 React 가져오기;
'./logo.svg'에서 로고 가져오기;
'@material-ui/core/CssBaseline'에서 CssBaseline 가져오기;

내보내기 기본 함수 App() {
반품 (

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

);
}

로컬 테스트의 경우:
라이브러리 node_modules에서 react 및 react-dom 폴더를 삭제합니다.
기본 패키지에서 "yarn install" 또는 "npm install"을 다시 실행하십시오.

이렇게 하면 반응의 두 번째 복사본이 기본 번들에 로드되는 것을 방지할 수 있습니다. 분명히 영구적 인 수정은 아니지만 로컬 테스트에는 작동합니다.

lerna를 사용하는 모든 사람은 코드가 다른 패키지의 구성 요소를 참조하는 한 패키지에서 테스트를 실행할 때 이 문제를 접할 수 있습니다.

이 경우 우리가 경험한 문제는 사양에서 임포트되는 반응과 Material UI의 후크를 사용하여 구현되는 Material UI의 withStyles 를 사용하는 구성 요소 트리의 구성 요소에서도 임포트되었기 때문입니다.

반응은 내부적으로 ReactCurrentDispatcher.current 변수의 상태를 관리하는 것으로 보이며 이는 결국 반응의 한 인스턴스에서 설정되지만 반응의 다른 인스턴스에서 사용됩니다. 비어 있을 때 Invalid hook call ... 를 던집니다.

우리는 이미 Craco 를 사용하여 빌드 시 Create React App의 webpack 구성을 재정의하고 있었습니다.

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

그러나 이 웹팩 재정의는 빌드 시에만 사용됩니다. 테스트를 실행할 때 코드는 빌드되지 않고 소스에서 인스턴스화됩니다. 따라서 우리의 솔루션은 craco.config.js 에서 CracoAlias 를 사용하여 지정하는 것이었습니다. 테스트 중 반응 경로:

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

@apieceofbart 의 예에 따라 꺼내지 않고 @craco/craco 를 솔루션으로 사용했습니다. 나를 위한 단계는 npm link 를 사용하여 로컬 모듈을 테스트하는 것이었습니다.

  1. npm i @craco/craco --save 를 실행하여 데모 앱에 craco를 설치합니다.
  2. 데모 앱에서 package.json이 있는 루트에 구성 파일 craco.config.js 을 만듭니다.
  3. 내 데모 앱에서 react-scriptscraco 로 바꿔 $ start , buildtest 스크립트를 변경합니다.
// 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"
  },
...
}

편집: @jasondarwin 이 같은 생각을 가지고 있다는 사실조차 알지 못했습니다.

이 문제를 해결하기 위해 하루를 보냈습니다. 누군가에게 도움이 될 경우를 대비하여 여기에 내 솔루션을 게시하십시오.

우리는 monorepo를 사용하고 있고 두 개의 패키지가 react에서 다른 인스턴스를 가져오고 있었지만 루트 노드 모듈의 동일한 위치로 확인되었습니다. 앱 중 하나가 자체 웹팩을 사용하여 번들을 생성했기 때문에 이 두 인스턴스가 있는 것으로 나타났습니다. 이것은 루트 노드 모듈로 올바르게 호이스트되었지만 해당 패키지에서 가져올 때 자체 인스턴스를 가져옵니다. 해결책은 webpack 구성의 외부에 react 및 react DOM을 포함하여 webpack이 번들에 대한 react의 새 인스턴스를 생성하지 않도록 하는 것이었습니다.

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

이것이 누군가를 돕기를 바랍니다!

나를 위해 그것은 react-hot-loader 버전 4.0.0을 사용하고 있었고 react-hot-loader 4.8로 업데이트하면 트릭을 수행하는 것 같습니다.

Modal 창으로 작업하기 위해 만들고 있는 사용자 정의 후크에서 테스트를 실행할 때만 Invalid hook call 메시지를 받습니다.

동작을 보여주기 위해 다음 예제를 만들었습니다.
(https://github.com/BradCandell/invalid-hook-example)

  • reactreact-dom 의 한 버전만

내가 아주 명백한 것을 놓치고 있습니까? 과거에 규칙을 어기면 npm start 가 실패합니다. 그러나 이것은 내 테스트에서만 실패합니다.

도움을 주셔서 감사합니다!
-브래드

웹팩 구성에 다음을 추가하여 문제를 해결했습니다.

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

처음에는 npm 링크의 문제라고 생각했고 제안된 모든 작업을 수행했으며 심지어 원사로 전환했습니다. 결국 다른 프로젝트에서 가져올 때 npm에 게시할 때 동일한 오류가 발생했을 때 다른 일이 일어나고 있다고 생각했습니다.

이것은 나를 위해 그것을 고쳤습니다. react-toastify를 가져오는데 잘못된 후크 호출이 발생했습니다. 콘솔 오류의 각 항목을 살펴보았습니다.

  1. React 및 React DOM 버전이 일치하지 않을 수 있습니다.

    1. Hooks의 규칙을 위반할 수 있습니다.

    2. 동일한 앱에 두 개 이상의 React 사본이 있을 수 있습니다.

3화로 마무리 되었습니다. 나는 이것을 따랐다:
https://reactjs.org/warnings/invalid-hook-call-warning.html#duplicate -반응

내가 _importing_했던 라이브러리와 react의 다른 사본을 번들로 묶고 있다는 것을 깨달을 때까지 위의 솔루션 중 어느 것도 효과가 없었습니다.
내 라이브러리의 소스 코드를 트랜스파일 및 번들링했기 때문에 문서에 나열된 React의 다른 버전에 대한 검사는 false true 를 반환했습니다.
react 를 외부 종속성으로 표시하고 내 라이브러리 번들에서 제외하는 것이 트릭이었습니다.

제 경우는 모노레포가 아니라 다소 비슷한 상황이었습니다. 우리는 새로운 UI 프레임워크를 개발 중이며 npm 링크 또는 lerna를 사용하는 대신 웹팩 별칭을 사용하여 형제 폴더에 파일이 있어야 합니다. 잘 작동하지만 이 문제가 발생합니다. 다행히 @apieceofbart 의 솔루션으로 문제가 해결되었습니다.

130:21행: React Hook "useStyles"는 React 기능 구성 요소나 사용자 정의 React Hook 기능이 아닌 "pharmacyDashboard" 기능에서 호출됩니다. react-hooks/rules-of-hooks
Line 133:45: React Hook "React.useState"는 React 기능 구성 요소나 사용자 정의 React Hook 기능이 아닌 "pharmacyDashboard" 기능에서 호출됩니다. react-hooks/rules-of-hooks

이것은 오류입니다 ..... 누구든지이 문제를 해결하는 데 도움을 줄 수 있습니까?

@vyshnaviryali usePharmacyDashboard 함수를 호출하는 것이 좋습니다.

./src/components/HomeFiles/AppFooter.js
1:1행: 'material-ui/no-hardcoded-labels' 규칙에 대한 정의가 material-ui/no-hardcoded-labels'를 찾을 수 없습니다.
누구든지이 문제를 해결하는 데 도움을 줄 수 있습니까?

구성 요소에 기능을 추가해야 하지만 테스트하기 전에 npm publish 를 원하지 않기 때문에 npm link 로 이 문제를 실행하는 모든 사람에게 $ yalc 사용을 제안한 사람이 아무도 없다는 사실에 놀랐습니다.

구성 요소에 기능을 추가해야 하지만 테스트하기 전에 npm publish 를 원하지 않기 때문에 npm link 로 이 문제를 실행하는 모든 사람에게 $ yalc 사용을 제안한 사람이 아무도 없다는 사실에 놀랐습니다.

나는 실제로 작년에 했습니다: https://github.com/facebook/react/issues/13991#issuecomment -535150839

거의 1년 동안 아무 문제 없이 사용하고 있습니다.

lerna를 사용하는 또 다른 것; 이 문제를 해결하기 위해 reactreact-dom 종속성을 루트 package.json 로 옮겼습니다.

나는 같은 문제가 있었고 다음을 추가하여 해결했습니다.

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

내 메인 앱의 webpack 구성에서 resolve 속성으로 변경합니다.

두 개의 React 사본을 사용한 것은 분명히 내 실수였지만 오류 메시지가 더 좋았더라면 좋았을 것이라는 데 동의합니다. 나는 이것이 아마도 다음과 유사하다고 생각합니다. #2402

위의 방법을 사용하고 있지만 jest를 실행할 때 여전히 오류가 발생하는 사람들을 위해 jest 구성의 moduleNameMapper 에 다음을 추가하십시오(필요하지 않은 경우 react-dom 생략).

moduleNameMapper: {

...

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

...

}

나는 길을 잃었다. 나는 이것을 얻었지만 내 앱은 후크를 사용하지 않으며 반응 또는 반응 영역 중복이 없습니다. 나는 next.js를 사용하고 있습니다. 그것과 관련이 있을까요?

npm ls react
npm ls react-dom

@maapteh 그게 나였어 ? 나는 그 명령을 실행했고 중복을 찾지 못했습니다. 두 라이브러리 모두 버전 16.13.1입니다.

@dancancro 저도 Next.js를 사용하고 있는데 이 문제를 해결할 수 없습니다.

npm ls reactnpm ls react-dom 둘 다 하나의 항목만 반환합니다. 하지만 그게 맞는지는 잘 모르겠습니다. 개발을 위해 로컬 패키지에 연결할 때 이 오류가 발생합니다. npm ls 는 종속성에서 반응을 기본 리포지토리에 다시 연결하지 않는 경우에도 하나의 항목만 반환합니다. 그러나 링크 반응을 제대로 수행하더라도 여전히 오류가 발생합니다.

@justincy 내 프로젝트에 패키지 링크가 없습니다. 나는 그것이 Next.js와 관련이 있다고 확신합니다. typeof document !== 'undefined' 내부에 주요 구성 요소를 넣으면 문제가 사라집니다. 효과적으로 Next.js의 목적을 훼손합니다.

종속성의 node_modules에서 react 및 react-dom을 삭제하여 문제를 해결했습니다. 이상적이지는 않지만 적어도 계속 일할 수 있습니다.

@dancancro 귀하의 문제가 Next.js로 인해 발생한 것인지 회의적입니다. 그렇다면 다른 많은 사람들이 문제를 겪을 것입니다. 연결된 패키지 때문에 실행 중입니다. 연결된 패키지가 없으면 오류가 표시되지 않습니다.

주 구성 요소의 7개 구성 요소 중 5개를 제거하면 문제가 사라집니다. 이 구성 요소에 대해 특별한 것을 볼 수 없습니다. typeof document !== 'undefined' 에서 이러한 구성 요소를 래핑하는 것도 작동합니다.

안녕하세요 팀, 저는 React 버전을 16.2.0에서 16.13.1로 업그레이드하려고 시도하고 있으며 react-dom에서도 동일한 작업을 수행했습니다.
이제 "/test"에서 호출되는 래퍼 구성 요소가 있습니다.

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

테스트 래퍼에서 후크가 있는 기능 구성 요소를 가져왔습니다.
function TestComponent(props) { useEffect(() => { console.log("TEST COMPONENT"); }); return ( <div> Hello world! </div> ) }

그러나 페이지가 렌더링될 때 UseEffect 후크가 작동하지 않고 오류가 발생합니다. 즉, 잘못된 후크 호출 경고
추신. :

  1. 나는 하나의 react와 react-dom이 설치되어 있는지 확인했습니다.
  2. React 및 react-dom 버전은 16.13.1입니다.

그게 내가 가진거야
난 그냥 ...
@ @
ReactError
나는 nextJS를 사용하므로 React 가져오기가 필요하지 않습니다. 그리고 나는 그것을 시도했다 - 도움이되지 않습니다.

다른 모든 페이지와 기능이 완벽하게 작동합니다.

@Brotipok next.js 의 버전은 무엇입니까? (비슷한 문제가 보이지만 9.4.X에서 9.5로 이동할 때만)

안녕!

동일한 오류가 발생했습니다. npm ls 할 때 react 및 react dom에 대해 하나의 패키지만 있습니다.

반응 버전: 16.13.1
React-dom 버전 : 16.13.1

저는 typescript를 사용하고 있으며 create-react-app my-app --template typescript로 프로젝트를 초기화했습니다.

기능 구성 요소는 내부에서 후크를 사용하지 않는 경우에만 작동합니다.

패키지.json

{
"이름": "blablamovie",
"버전": "0.1.0",
"비공개": 사실,
"종속성": {
"@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",
"@유형/노드": "^12.12.53",
"@types/react": "^16.9.43",
"@types/react-dom": "^16.9.8",
"@types/react-router-dom": "^5.1.5",
"반응 아이콘": "^3.10.0",
"반응 스크립트": "3.4.1",
"typescript": "^3.7.5",
"웹팩 번들 분석기": "^3.8.0"
},
"스크립트": {
"시작": "반응 스크립트 시작",
"빌드": "반응 스크립트 빌드",
"테스트": "반응 스크립트 테스트",
"꺼내기": "반응 스크립트 꺼내기",
"분석": "소스 맵 탐색기 '빌드/정적/js/*.js'"
},
"eslintConfig": {
"확장": "반응 앱"
},
"브라우저 목록": {
"생산": [
">0.2%",
"죽지 않았다",
"op_mini 모두가 아닙니다"
],
"개발": [
"마지막 1 크롬 버전",
"최근 1개의 파이어폭스 버전",
"마지막 1 사파리 버전"
]
}
}
나는 중요한 프로젝트이고 그것은 나를 약간 미치게 만들고 있습니다.
누군가 도울 수 있다면 좋을 것입니다.
감사 해요.

@Brotipok next.js 의 버전은 무엇입니까? (비슷한 문제가 보이지만 9.4.X에서 9.5로 이동할 때만)

다음은 종속성입니다.
"종속성": {
"다음": "9.4.4",
"다음 이미지": "^1.4.0",
"node-sass": "^4.14.1",
"반응": "16.13.1",
"react-document-meta": "^3.0.0-beta.2",
"반응돔": "16.13.1",
"반응 수평 타임라인": "^1.5.3",
"반응 메타 태그": "^0.7.4",
"react-onclickoutside": "^6.9.0"
},
"devDependencies": {
"@유형/노드": "^14.0.23",
"@types/react": "^16.9.43",
"typescript": "^3.9.7"
}

material-ui/core/Dialog 구성 요소를 가져올 때 이와 동일한 문제가 발생합니다. reactreact-dom 모두에 대해 16.8.0 반응을 사용하도록 $# package.json 를 설정했습니다. react-dom 수입.

npm ls reactnpm ls react-dom 를 단 한 번의 가져오기로 실행했으며 오류 페이지에 설명된 테스트도 시도했습니다.

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

false 반환하지만 종속성에서 가져오는 "다른" 반응 버전을 어떻게 추적합니까? Material UI Dialog 구성 요소를 가져올 때만 발생하는 것 같습니다. 탭하자마자 발생합니다. 렌더링을 위해 트리거하는 버튼입니다. ListListItems 등과 같은 다른 구성 요소를 사용할 수 있습니다.

강제로 해결 을 시도했지만 해결되지 않았습니다.

나는 웹 팩(정말 작은 프로젝트)을 사용하지 않으므로 차이가 있다면 빌드가 react-scripts build 로 발생합니다.

다시 작성: 내 질문을 솔루션 참조로 대체하겠습니다.

배경:
브라우저의 바닐라 JS에서 해당 구성 요소를 호출할 수 있는 자산에 후크가 있는 기능 구성 요소를 웹팩 컴파일하려고 했습니다.

예를 들어,

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

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

...그 자체로 모듈로 내보내고 해당 자산을 로드한 후 다음과 유사하게 HTML에서 직접 사용하고 싶었습니다.

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

구성 요소에 후크가 포함되어 있지 않은 한 오래 전에 이 작업을 수행했습니다. 그러나 후크를 사용할 때 이 두려운 오류 메시지가 계속 발생했습니다.

테이블을 뒤집을 정도로 간단한 솔루션
나는 더 복잡한 red herrings(여러 react/reactDOM 버전/인스턴스, npm 가져오기 및 숨겨진 보조 종속성, react-hot-loader, webpack 설정, 외부, 다른 번들/모듈/라이브러리 규칙, 컴파일 후 구조)를 _많이_ 따랐습니다. .) 이것을 시도하기 전에 효과가 있었습니다.

export default () => <Example />;

(또는 해당되는 경우 export default props => <Example {...props} /> ).

회고 20/20에서는 그것이 의미가 있다고 생각합니다.

그러나 다른 누군가가 그것을 필요로 할 경우를 대비하여 혼란의 원인을 정확히 지적하기 위해: 후크 규칙 문서는 _함수 구성 요소 본문의 최상위 수준에서 호출하라고 말합니다. 실제로 예제를 내 구조에 직접 붙여 넣었기 때문에 그렇게 생각했습니다.

내 해석은 이것이 , 예에서 ...

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

... 자체 가 함수 구성 요소 가 아닌가요? 올바른 호출 컨텍스트에서 그렇게 됩니다( Example() 가 아니라 <Example /> ).

문서의 다른 곳에서 놓쳤을 수도 있지만 그렇지 않은 경우: 약간의 사용 컨텍스트(또는 ES 모듈 설정)가 포함/언급/링크된 경우 많은 시간을 절약할 수 있었습니다. :) 특히 직접 export default Example 버전은 후크 없이 작동합니다.

작동하는 솔루션 @apieceofbart에 감사드립니다! 내 문제는 npm 링크와 관련이 있습니다.

다음은 Webpack 구성이 의도적으로 숨겨져 있는 Create React App으로 작업하는 방법입니다. @florianzemma도 솔루션이 될 수 있습니까?

  1. npm install -D react-app-rewired
  2. 프로젝트 루트에서 config-overrides.js 라는 파일을 만듭니다.
// 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. package.json 의 관련 react-scripts ... -commands 를 react-app-rewired ... 로 바꿉니다.

도움이 되기를 바랍니다.

번들을 2번 로드했기 때문에 이 오류가 발생했습니다.
제 경우에는 스크립트 태그가 렌더링된 nunjucks 템플릿이 레이아웃 자체에서, 그리고 일반적으로 헤드 태그 콘텐츠용 템플릿에서 2번 사용되었기 때문에 발생했습니다.

원사 해결 방법

저는 Yarn을 사용하고 있으며 package.json 에서 강제로 해결 하여 이 문제를 해결했습니다.

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

상위 앱(라이브러리 소비)에 해상도를 추가하는 것 외에도 다음 명령으로 라이브러리 종속성을 업데이트했습니다.

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

이 후 yarn add link:/path/to/library 로 상위 앱의 라이브러리를 다시 연결했습니다.

안녕
원사 작업 공간에서 동일한 문제가 발생합니다.
다음과 같은 레이아웃이 있습니다.

작업 공간/
├── 도서관/
├── 앱1/
├── 앱2/

app1과 app2는 react v16.9.0, react-dom v16.9.0 및 'library'에 대한 직접적인 종속성을 가지고 있습니다.
'라이브러리'는 v16.9.0에 반응하는 피어 종속성과 스토리북에 대한 개발자 종속성이 있습니다.
문제는 react v16.13.1에 종속된 스토리북에서 비롯된 것 같습니다.
그러나 yarn install을 실행하면 최상위 node_modules에서 반응 16.13.1로 끝나고 app1 및 app2의 로컬 node_modules에서 반응 16.9.0으로 끝납니다.

app1(CRA로 생성)을 실행할 때 로컬 react v16.9.0을 사용하고 있지만 'library'의 구성 요소는 React v16.13.1을 사용하고 있습니다.

이것은 원사 호이스팅 로직, create-react-apps' webpack 정의 또는 둘 다에 문제가 있는 것 같습니다.
누구든지 이 시나리오에 대한 해결 방법에 대한 아이디어가 있습니까?

안녕
원사 작업 공간에서 동일한 문제가 발생합니다.
다음과 같은 레이아웃이 있습니다.

작업 공간/
├── 도서관/
├── 앱1/
├── 앱2/

app1과 app2는 react v16.9.0, react-dom v16.9.0 및 'library'에 대한 직접적인 종속성을 가지고 있습니다.
'라이브러리'는 v16.9.0에 반응하는 피어 종속성과 스토리북에 대한 개발자 종속성이 있습니다.
문제는 react v16.13.1에 종속된 스토리북에서 비롯된 것 같습니다.
그러나 yarn install을 실행하면 최상위 node_modules에서 반응 16.13.1로 끝나고 app1 및 app2의 로컬 node_modules에서 반응 16.9.0으로 끝납니다.

app1(CRA로 생성)을 실행할 때 로컬 react v16.9.0을 사용하고 있지만 'library'의 구성 요소는 React v16.13.1을 사용하고 있습니다.

이것은 원사 호이스팅 로직, create-react-apps' webpack 정의 또는 둘 다에 문제가 있는 것 같습니다.
누구든지 이 시나리오에 대한 해결 방법에 대한 아이디어가 있습니까?

이에 대해 내가 찾은 유일한 해결책은 CRA 앱을 yarn run eject 하고 resolve 섹션의 순서를 다음에서 전환하는 것입니다.

```자바스크립트
모듈: ['노드_모듈', 경로.appNodeModules].concat(
module.additionalModulePaths || []
),
````

에게
```자바스크립트
모듈: [경로.appNodeModules, '노드 모듈'].concat(
module.additionalModulePaths || []
),
````

'appNodeModules'가 최우선 순위가 아니라는 것이 이상하게 보입니다. 종속성을 해결할 때 문제의 실제 앱을 연기해야 ​​합니까?

Webpack 및 Electron과 관련된 설정에서 '후크' 문제가 발생했습니다. 내 프로젝트는 Webpack에서 자체적으로 번들로 제공하는(그리고 내가 직접 작성한) 모듈 A에 대한 종속성이 있습니다. A에서 React를 외부화했습니다(commonjs2 모듈로 선언). 이것은 라이브러리 번들에서 React 파일을 제외합니다.

Electron Renderer 프로세스에서 실행되는 제 메인 프로그램도 React를 사용합니다. Webpack에 React를 번들에 포함시켰습니다(특별 구성 없음).

그러나 이것은 런타임 환경에서 두 개의 React 인스턴스로 인해 '후크' 문제를 발생시켰습니다.

이것은 다음 사실로 인해 발생합니다.

  • 모듈 A는 React를 '요구'하고 이것은 Electron의 모듈 시스템에 의해 해결됩니다. 따라서 Electron은 node_modules에서 React를 가져옵니다.
  • 메인 프로그램은 번들 자체에서 React를 '로드'하기 위해 Webpack 런타임에 의존합니다.
  • Electron과 Webpack 런타임에는 모두 자체 모듈 캐시가 있습니다...

내 솔루션은 메인 프로그램에서도 React를 외부화하는 것이었습니다. 이런 식으로 메인 프로그램과 모듈 A는 모두 메모리의 단일 인스턴스인 Electron에서 React를 가져옵니다.

여러 별칭을 시도했지만 별칭이 모듈 코드를 찾을 위치를 Webpack에 지시할 뿐이므로 문제가 해결되지 않습니다. 다중 모듈 캐시의 문제와 관련하여 아무 것도 하지 않습니다!

제어할 수 없는 모듈에서 이 문제가 발생하면 React가 외부화되었는지 여부와 방법을 알아보세요. 외현화하지 않으면 Electron의 맥락에서 이 문제를 해결할 수 없다고 생각합니다. 전역으로 외부화되는 경우 React를 .html 파일에 넣고 기본 프로그램도 이에 종속되도록 만듭니다.

마침내...

//webpack.config.js

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

Vue3에는 동일한 문제가 있습니다.

React를 사용하는 외부 라이브러리의 package.json에 reactreact-dompeerDependencies 로 넣어 이 문제를 해결했습니다.

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

문서의 다른 곳에서 놓쳤을 수도 있지만 그렇지 않은 경우: 약간의 사용 컨텍스트(또는 ES 모듈 설정)가 포함/언급/링크된 경우 많은 시간을 절약할 수 있었습니다. :) 특히 직접 export default Example 버전은 후크 없이 작동합니다.

안녕하세요 @espen42 입니다 .
나는 당신의 솔루션이 우리에게 도움이 되기를 정말로 바랐습니다. 우리는 당신이 언급한 것처럼 말 그대로 _모든 것_을 시도했습니다.

불행히도 귀하의 솔루션도 도움이 되지 않는 것 같습니다. 내가 방금 뭔가를 놓친 게 아닐까?

따라서 패키지(@bla/bla라고 부를 것입니다)에는 다음과 같이 후크가 있는 구성 요소가 있는 index.js 가 있습니다.

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

npx babel 를 사용하여 패키지를 컴파일합니다.

이 패키지를 npm link 와 연결한 다음 npm link @bla/bla 와 같은 프로젝트에 포함합니다.
패키지와 프로젝트 모두 동일한 버전의 React 및 react-dom을 사용합니다.

프로젝트에서 다음과 같은 패키지를 포함합니다.

import Bla from `@bla/bla`

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

export default RenderBla

불행히도 오류는 여전히 지속됩니다.
Invalid hook call. Hooks can only be called inside of the body of a function component.

우리는 무엇을 놓칠 수 있습니까?

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

이것은 나를 위해 문제를 해결했습니다. 정말 감사합니다. ❤️

외부 링크를 통해 액세스할 때 필드 사용자 지정 오류(Sharepoint Online)

링크를 통해 액세스할 때 패브릭 UI 버전에 따라 다음 오류 중 하나가 발생하는 몇 가지 패브릭 ui 구성 요소가 있는 spfx 필드 사용자 정의 확장 프로그램:
https://reactjs.org/docs/error-decoder.html/?invariant=321 ,
https://reactjs.org/docs/error-decoder.html/?invariant=290&args []=A.%20일반

페이지를 새로 고치면 모든 것이 제대로 작동합니다.
코드에서 React Hooks를 사용하지 않고 React Components만 사용했습니다.
ref도 사용하지 않았습니다.

Fabric ui 구성 요소를 모두 제거해도 오류가 발생하지 않는 Fabric ui 때문일 수 있습니다.

다른 버전의 fabic ui, 6.189.2, 6.214.0 및 7.114.1을 시도하고 모든 fabric-ui 참조를 유창한 ui로 교체하려고 시도했지만 여전히 문제가 지속됩니다.

반응 버전을 확인했습니다. 출력은 다음과 같습니다.
npm ls 반응
+-- @microsoft/ [email protected]
| +-- @microsoft/office-ui-fabric-react-bundle@ 1.9.1
| | -- [email protected] deduped | +-- @microsoft/[email protected] | | -- [email protected] 중복 제거됨
| +-- @microsoft/ [email protected]
| | -- [email protected] deduped | -- [email protected] 중복 제거됨
`-- 반응@16.8.5

안녕하세요 여러분,
나는 또한이 성가신 오류를 발견했습니다. 내 경우에는 결국 내 webpack 빌드의 구성이 잘못되었습니다. 그러나 이 문제에서 제안된 사항 중 어느 것도 저에게 효과가 없었습니다. 그래서 제 경험도 공유하고 싶습니다.

내 페이지에는 여러 진입점이 있으며 SplitChunkPlugin은 런타임 청크를 생성할 수 있습니다. 우리는 rails-webpacker gem을 사용하고 있기 때문에 기본적으로 각 청크에 대한 런타임을 생성하도록 구성되어 있습니다. 그러나 webpack은 기본적으로 비슷한 작업을 수행하며 청크 내부에 런타임을 포함합니다.

물론 문서에서는 이 경우에 대해 경고하지만 찾아야 합니다. optimization.runtimeChunksingle 로 설정하면 별도의 런타임이 생성됩니다. 이렇게 하면 여러 진입점에서 반응을 사용할 때 빌드가 반응의 여러 복사본을 인스턴스화하는 것을 방지할 수 있습니다.

https://webpack.js.org/configuration/optimization/#optimizationruntimechunk 참조

안녕 모두들,
CDN에서 가져오고 <script> 태그에 포함된 외부 라이브러리를 사용하려는 문제가 있어서 코드 자체로 할 수 있는 일은 많지 않습니다. lib는 반응과 후크를 사용하므로
3. You might have more than one copy of React in the same app 오류입니다.
슬프게도 라이브러리에 대한 NPM 패키지가 없습니다: https://github.com/Anyline/anyline-ocr-anylinejs-module
CRA를 사용하고 있으며 프로젝트가 배출되지 않습니다.

작은 예제 Sandbox 를 만들었습니다.

다른 패키지도 후크를 사용하지만 자체 React를 사용하기 때문에 동일한 오류가 발생합니다. 내 패키지를 NPM에 게시한 다음 NPM에서 직접 가져와야 했습니다. 저것

나는 최근에이 문제에 와서 이유가 궁금합니다.
GitLab에 업로드하고 주소로 설치하여 해결했습니다.
패키지와 로컬 패키지의 차이점은 무엇입니까?

"잘못된 후크 호출"이 발생하는 것을 발견했습니다. 후크를 호출하는 구성 요소를 동적으로 로드할 때.

코드 샌드박스

"앱"을 로드하는 테스트는 정적으로 통과합니다. 동적으로 로드하는 두 가지 테스트(하나는 require , 하나는 import 를 함수로 사용) 모두 오류가 발생합니다.

내가 관심을 갖는 이유: jest.doMock을 사용하여 몇 가지를 조롱한 다음 문서에 따라 테스트하려는 모듈을 동적으로 로드하는 테스트를 작성하려고 합니다. 다른 기능에서 다르게 조롱할 수 있어야 하기 때문에 Mock 대신 doMock을 사용하고 있습니다. 하지만 조롱 없이 오류가 발생한다는 것을 알 수 있습니다.

다른 패키지도 후크를 사용하지만 자체 React를 사용하기 때문에 동일한 오류가 발생합니다. 내 패키지를 NPM에 게시한 다음 NPM에서 직접 가져와야 했습니다. 저것

나는 최근에이 문제에 와서 이유가 궁금합니다.
GitLab에 업로드하고 주소로 설치하여 해결했습니다.
패키지와 로컬 패키지의 차이점은 무엇입니까?

@catsheueReact1 === React2 true 였나요?
나는 내 것이 npm에 게시되지 않았지만 그것이 원인인지 알고 싶었습니다.

내 반응 라이브러리를 프로젝트로 가져올 때 왜 이런 일이 일어나는지 해결책을 찾지 못했습니다 React1 === React2 = true

yarn link 를 사용하여 로컬 라이브러리를 테스트하는 것과 동일한 문제가 발생했습니다. 내 실수는 reactreact-dom 를 피어가 아닌 개발 종속성으로 나열한 것입니다.

그래서 yarn add --peer react react-dom 했어야 했습니다. 마지막으로 React를 개발자 종속성으로 커밋하는 데 이미 실수를 저질렀기 때문에 라이브러리에서 node_modules를 제거해야 했습니다. rm -rf node_modules; yarn 이 문제를 해결했습니다.

나도이 문제에 직면했습니다. 제 경우에는 Storybook(v6.0.28)의 중복된 React로 인해 발생했습니다. 나는 당신이 여기에서 더 많은 정보를 찾을 수 있다고 믿습니다.

Storybook 종속성을 제거하고 node_modules 를 삭제한 다음 yarn install 를 다시 실행했습니다. 이것은 나를 위해 일했습니다. 누군가가 눈물과 낭비 시간을 피하는 데 도움이되기를 바랍니다.

이 해결 방법은 저에게도 효과적입니다. Firebase Functions를 사용하고 있으며 프로젝트 루트와 /functions/ 디렉토리 모두에 node_modules 폴더가 있습니다. /functions/node_modules 를 삭제하면 앱이 제대로 실행됩니다. 이것은 해결 방법이지만 상당히 짜증납니다. node_modules 폴더가 동시에 존재할 수 있는 해결 방법을 찾은 사람이 있습니까?

후세와 create-react-app 로 만든 앱에서 mdbootstrap을 사용할 때 이 문제에 직면할 수 있는 모든 사람을 위해.

버튼 및 카드 이미지와 같은 다양한 mdbootstrap 구성 요소를 추가할 때 이 오류가 발생했습니다. React 지원 문서에 따라 문제 해결을 위해 index.js에 추가된 콘솔 출력은 버전 비교 시 true 를 반환했습니다. 그래서 나는 다른 것을 시도해야했습니다.

수정은 npm dedupe 를 실행하는 것이었습니다.

npm ls react

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

npm dedupe

npm ls react

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

그 후 모든 구성 요소가 제대로 작동했습니다. 행복한 날들.

"잘못된 후크 호출"이 발생하는 것을 발견했습니다. 후크를 호출하는 구성 요소를 동적으로 로드할 때.

코드 샌드박스

"앱"을 로드하는 테스트는 정적으로 통과합니다. 동적으로 로드하는 두 가지 테스트(하나는 require , 하나는 import 를 함수로 사용) 모두 오류가 발생합니다.

내가 관심을 갖는 이유: jest.doMock을 사용하여 몇 가지를 조롱한 다음 문서에 따라 테스트하려는 모듈을 동적으로 로드하는 테스트를 작성하려고 합니다. 다른 기능에서 다르게 조롱할 수 있어야 하기 때문에 Mock 대신 doMock을 사용하고 있습니다. 하지만 조롱 없이 오류가 발생한다는 것을 알 수 있습니다.

@miket01 정확히 내가 하려고 하는 것(그러나 조롱은 없음). 해결책을 찾으셨습니까?

이 작업을 수행했습니다.

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

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

useState 먼저 호출하여 수정:

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

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

몇 달 동안 따로 설정한 후에도 이 오류가 계속 발생합니다.

내 프로그램에서 제로 후크를 사용합니다. react 의 사본이 정확히 하나와 react-dom 의 사본이 하나 있으며 동일한 버전입니다. 링크가 없습니다.

최근에 보안 문제를 해결하기 위해 몇 가지 패키지를 업데이트하기 전에 부분적으로 작동했습니다. 저는 next.js를 사용하고 있으며 {typeof window !== 'undefined' 로 감싸서 최상위 구성 요소에서 일부 하위 구성 요소를 제외하는 것이 수정되었지만 이제는 작동하지 않습니다.

[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

ReactCurrentDispatcher.current === null 때문에 오류 가 발생했지만 /node_modules/react/cjs/react.development.js 에서 이것이 무언가로 설정된 곳을 찾을 수 없습니다.

누군가 ReactCurrentDispatcher.current 가 가치를 얻어야 하는 곳을 말해 줄 수 있습니까?
https://github.com/facebook/react/search?p=2&q=%22ReactCurrentDispatcher.current+%3D%22&type=code

이것은 후보처럼 보이지만 이 코드는 내 react-development.js 에 포함되어 있지 않습니다. 그래야 합니까?

    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

next.js 의 서버 측 렌더링에서 이 오류가 발생하고 이 코드는 react-dom/server 아래의 반응 소스에 있습니다. /node_modules/react/cjs/react-development.js 이 올바른지 어떻게 확인할 수 있습니까?

업데이트: 이것이 문제였습니다. next.config.js 파일에서 webpack.config.externals 를 수정했습니다.
https://github.com/vercel/next.js/issues/17592#issuecomment -712443172

내 앱에 머티리얼 UI를 통합하려고 할 때마다 엄청난 오류(잘못된 후크 호출)가 발생합니다. 저는 React를 처음 접해서 도움이 필요합니다.

이 페이지가 도움이 되었나요?
0 / 5 - 0 등급