React Hooks 오류 : 후크는 함수 구성 요소의 본문 내에서만 호출 할 수 있습니다.


78

useState후크를 사용할 때이 오류가 발생합니다 . 참조를 위해 반응 문서 를 살펴보면서 기본 형식으로되어 있지만 여전히이 오류가 발생합니다. 얼굴 손바닥 순간을 맞이할 준비가되었습니다 ...

export function Header() {
  const [count, setCount] = useState(0)
  return <span>header</span>
}

2
나를 위해 작동합니다 ... 오류 없음 ... 16.7로 업데이트 했습니까?
SakoBu 2010 년

그래요. 내 설정과 관련이있을 수 있다고 생각하지만 그게 뭔지 모르겠습니다. 이벤트 함수 앱 구성 요소 상단에서 동일한 후크를 사용하면 동일한 오류가 발생합니다.
loganfromlogan

흠 ... 모든 내가 만들-반응 - 응용 프로그램 newhook 다음 원사 추가 NPX했다 않았다 @ 다음과 반응-DOM과는 일 @ 다음 잘 ... 반응
SakoBu

8
여기서 끝나는 모든 사람에게 참고로, 후크가 작동하려면 React와 ReactDOM을 @next로 업데이트해야합니다. 그렇지 않으면 반응이 위의 오류를 던질 것입니다. 나는 방금이 문제가 있었고 그것이 내 해결책 이었기 때문에 알고 있습니다.
Tony

답변:


40

업데이트 : 2018 년 12 월

의 새 버전이 출시 react-hot-loader되었습니다 . 링크 . Hooks는 이제 즉시 작동합니다. 저자 theKashey에게 감사드립니다.

이 상용구 https://github.com/ReeganExE/react-hooks-boilerplate를 확인 하십시오.

  • React Hooks
  • 반응 핫 로더
  • Webpack, Babel, ESLint Airbnb

이전 답변 :

먼저 react@nextreact-dom@next.

그런 다음 사용 중인지 확인하십시오 react-hot-loader.

제 경우에는 핫 로더를 비활성화하면 HMR이 작동 할 수 있습니다.

https://github.com/gaearon/react-hot-loader/issues/1088을 참조 하세요 .

인용 :

예. RHL은 후크와 100 % 호환되지 않습니다. 그 뒤에는 몇 가지 이유가 있습니다.

SFC는 클래스 구성 요소로 변환됩니다. SFC에 "update"메서드가없는 한 HMR에서 강제 업데이트 할 수있는 이유가 있습니다. 업데이트를 강제하는 다른 방법을 찾고 있습니다 (예 : RHL이 SFC를 죽이고 있습니다.

"hotReplacementRender". RHL은 React의 작업을 수행하고 이전 앱과 새 앱을 렌더링하여 병합하려고합니다. 그래서 분명히 지금은 깨졌습니다.

두 문제를 모두 완화하기 위해 PR 초안을 작성하겠습니다. 작동하지만 오늘은 아닙니다.

작동하는 더 적절한 수정이 있습니다- 콜드 API

모든 사용자 지정 유형에 대해 RHL을 비활성화 할 수 있습니다.

import { cold } from 'react-hot-loader';

cold(MyComponent);

"useState/useEffect"내부 구성 요소 소스 코드를 검색 하고 "콜드"합니다.

업데이트 :

react-hot-loader 관리자의 업데이트에 따라 다음 react-hot-loader@next과 같이 구성을 시도 하고 설정할 수 있습니다 .

import { setConfig } from 'react-hot-loader';

setConfig({
  // set this flag to support SFC if patch is not landed
  pureSFC: true
});

업데이트에 대해 @loganfromlogan에게 감사드립니다.


이것을 지적 해 주셔서 감사합니다 :). react-hot-loader를 사용하고 있으므로 작동하지 않는 것이 합리적입니다. 그러나 나는 아직 다른 일이 일어나지 않을 것이라고 100 % 확신하지 못합니다. 나는 react-hot-loader에서이 문제를 따르고 수정 사항이 게시 된 후이 질문을 업데이트 할 것입니다.
loganfromlogan

이제 react-hot-loader를 비활성화하면이 오류가 해결되었음을 확인할 수 있습니다.
loganfromlogan 2018 년

2
추가하려면 혹시라도 구성 요소를 인라인 jsx 함수 호출로 렌더링하는 경우 구성 요소가로 래핑 된 경우에도 여전히 오류가 발생합니다 cold. 그래서 {MyComponent(props)}작동하지 않을 <MyComponent {...props} />것입니다.
Dimitar Nikovski

이제 react-hot-loader로이 작업을 수행 할 수있는 방법이 있습니다. 의 메인테이너에서이 댓글을 참조하십시오 반응 핫 로더, github.com/gaearon/react-hot-loader/issues/...
loganfromlogan

32

내 문제는 react-dom모듈 업데이트를 잊었습니다 . 문제를 참조하십시오 .


3
나도! 나는 create-react-app 및 Typescript를 사용하고 있습니다
jugglingcats

1
나는 react 및 react-dom 버전 16.8.3을 사용하고 있지만 여전히 같은 문제가 있습니다
huykon225

16

같은 문제가있었습니다. 내 문제는 React Router와 관련이 있습니다. 나는 실수로 사용했다

<Route render={ComponentUsingHooks} />

대신에

<Route component={ComponentUsingHooks} />

1
이 댓글은 내 생명도 구했습니다. 그것에 3 시간을 낭비하고 내 프로젝트를 산산조각 냈다. 라우터에 오타가 있었
벤 Gannaway

3

컴포넌트 파일에서 React의 기본 후크를 가져온 다음 사용자 지정 후크에 전달하여이 문제를 해결할 수있었습니다. 어떤 이유로 사용자 지정 후크 파일에서 React 후크 (예 : useState)를 가져올 때만 오류가 발생합니다.

내 구성 요소 파일에서 useState를 가져옵니다.

import React, {useState} from 'react'; // import useState

import {useCustomHook} from '../hooks/custom-hook'; // import custom hook

const initialState = {items: []};
export default function MyComponent(props) {
    const [state, actions] = useCustomHook(initialState, {useState});
    ...
}

그런 다음 내 후크 파일에서 :

// do not import useState here

export function useCustomHook(initialValue, {useState}) {
    const [state, setState] = useState(initialValue || {items: []});

    const actions = {
        add: (item) => setState(currentState => {
            const newItems = currentState.items.concat([item]);
            return {
                ...currentState,
                items: newItems,
            };
        }),
    };

    return [state, actions];
}

이 방법은 기본 후크를 제공하기 위해 React의 라이브러리를 모의 할 필요가 없기 때문에 후크의 테스트 가능성을 향상 시켰습니다. 대신 모의 useState후크를 사용자 지정 후크의 함수에 바로 전달할 수 있습니다 . 사용자 지정 후크가 이제 React 라이브러리와 결합되지 않아보다 자연스러운 기능 프로그래밍 및 테스트를 허용하므로 코드 품질이 향상된다고 생각합니다.



3

패키지 docz가 사용 react@16.6.3되었고 최종 출력 번들에 두 개의 반응 버전이 있는 monorepo에서 문제가 발생했습니다 .

Github의 문제

패키지를 제거하여 수정했습니다 😅


2

나에게 문제는 실제로 react-hot-loader 입니다.

다음 과 같은 방법을 사용하여 전체 앱 대신 단일 구성 요소에 대해 react-hot-loader를 비활성화 할 수 있습니다 cold.

import { cold } from 'react-hot-loader'

export const YourComponent = cold(() => {

  // ... hook code

  return (
    // ...
  )
})

또는

export default cold(YourComponent)

2

그냥 포함 @ rista404의 대답에 정교하게 중복 된 버전react(아마와 react-dom당신이 당신의 후크를 사용하는 위치에 따라 같은 오류를 얻을 것이다). 다음은 두 가지 예입니다.

  1. 외부 의존성의 다른 버전이 포함되어 react그것에서을 dependencies로 가능성이 실수로, react일반적으로 피어 의존해야한다. 경우 npm자동으로 로컬 버전과이 버전을 중복 제거하지 않습니다,이 오류가 표시 될 수 있습니다. 이것이 @ rista404가 언급 한 것입니다.
  2. 당신 npm link이 포함 된 패키지 react의에 devDependenciesdependencies. 이제이 패키지의 모듈에 대해 상위 프로젝트가 아닌 react로컬 node_modules디렉토리 에서 다른 버전을 가져 오면 오류가 표시 될 수 있습니다 .

후자는 다음 과 같이 webpack사용하여 번들로 묶을 때 수정할 수 있습니다 resolve.alias.

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

이렇게하면 react항상 상위 프로젝트의 node_modules디렉토리 에서 가져옵니다 .


2

MobX을 사용하고있는 구성 요소를 포장 할 때이 문제를 건너 사람들을 위해 observer, 당신이 사용할 수 있도록 mobx-react-lite대신 mobx-react.

5 월 29 일 업데이트

이후 mobx-react 6.0.0부터 후크 기반 구성 요소는 이제 mobx-react 에서 지원 되므로 mobx-react-lite더 이상 사용할 필요가 없습니다 (문제가 발생한 경우).


1

이 해결 방법을 찾았습니다. react-hot-loaderPR이 인바운드를 수정하는 동안 습니다.

후크를 호출하는 함수를으로 래핑하여 React.memo변경되지 않은 경우 핫 리로드를 방지합니다.

const MyFunc = React.memo(({props}) => {...

솔루션 크레딧 : https://github.com/gatsbyjs/gatsby/issues/9489


1

내 문제는 다음과 같습니다.

나는하고 있었다: ReactDOM.render(Example(), app);

내가해야만했던 반면 : ReactDOM.render(<Example />, app);


1
이것은 내 문제이기도했으며 여기에 대한 답변 중에서 찾을 수있어서 기쁩니다.
Seth Bro

이것은 또한 내 문제였으며 여기에 대한 답변 중에서 찾을 수있어서 기쁩니다. 나는 그것이 내 원인의 미묘한 어리 석음 일 것이라고 생각했지만 번 들러 에서 모듈 복제에 대한 실제 문제 가 분명히 있기 때문에 4 시간 동안 연구 분노의 토끼 구멍을 뚫었습니다. 자존심을 희생하면서 제 정신을 회복하게되어 기쁩니다.
Seth Bro

1

원사 작업 공간의 동료 사용자를 위해 여기에 내 상황과 그것을 알아 낸 방법이 있습니다.

  • 패키지
    • foo
      • react@16.8.6
      • 반응 @ 16.10.1

Invalid Hook Call Warning 의 Facebook 문서 는 yarn 작업 공간에 대해 아무것도 말하지 않았으므로 내 구성이 정확하다고 가정했습니다. 그러나 그렇지 않았습니다. 모든 패키지 에서 동일한 버전을 사용해야 만 오류를 수정할 수 있습니다 .

위의 예에서 react 버전을 "foo"에서 16.10.1로 변경하여 "bar"의 반응 버전과 일치하도록해야합니다.

보너스 : GitHub에서이 토론을 참조 하여 인터넷에서 오프로드 된 아름다운 정서적 수하물 컬렉션을 확인하십시오.



0

Create React App을 사용하는 경우 "react-scripts"react 및 react-dom 버전으로 버전 을 업데이트해야합니다 .

 "react-scripts": "2.1.5",
 "react": "^16.8.1",
 "react-dom": "^16.8.1",

이 조합은 잘 작동합니다.




-5

package.json react-dom 버전을 반응으로 업데이트


"^ 16.7.0 - alpha.0"을 "-DOM 반응": "반응" "^ 16.7.0 - alpha.0"
shisongyan

5
대답은 단지 제안 일 경우, 댓글 섹션 사용할 수 있습니다
AirCodeOne
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.