Front-End

[React] Uncaught Error: Invalid hook call. 에러 해결

madylin 2024. 5. 12. 16:09
반응형

모달창이 close 될 때마다 관련 state 를 초기화해주는 함수를 호출하는데, 세개의 파일에서 동일한 함수를 추가해 쓰고 있었다.

반복되는 코드를 줄이기 위해서, 함수를 새 파일로 뺀 후 컴포넌트처럼 호출해서 쓰려고 수정했더니 아래처럼 에러가 났다.

 

Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
    at Object.throwInvalidHookError (react-dom.development.js:16227:9)
    at useContext (react.development.js:1618:21)
    at useStoreRef (index.js:4223:27)
    at useSetRecoilState (index.js:5386:20)
    at Module.closeMakeLetter (CloseMakeLetter.jsx:6:27)
    at onClick (TopOfChooseBOB.jsx?t=1699959157546:50:54)
    at HTMLUnknownElement.callCallback2 (react-dom.development.js:4164:14)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:4213:16)
    at invokeGuardedCallback (react-dom.development.js:4277:31)
    at invokeGuardedCallbackAndCatchFirstError (react-dom.development.js:4291:25)
throwInvalidHookError @ react-dom.development.js:16227
useContext @ react.development.js:1618
useStoreRef @ index.js:4223
useSetRecoilState @ index.js:5386
closeMakeLetter @ CloseMakeLetter.jsx:6
onClick @ TopOfChooseBOB.jsx?t=1699959157546:50
callCallback2 @ react-dom.development.js:4164
invokeGuardedCallbackDev @ react-dom.development.js:4213
invokeGuardedCallback @ react-dom.development.js:4277
invokeGuardedCallbackAndCatchFirstError @ react-dom.development.js:4291
executeDispatch @ react-dom.development.js:9041
processDispatchQueueItemsInOrder @ react-dom.development.js:9073
processDispatchQueue @ react-dom.development.js:9086
dispatchEventsForPlugins @ react-dom.development.js:9097
(익명) @ react-dom.development.js:9288
batchedUpdates$1 @ react-dom.development.js:26140
batchedUpdates @ react-dom.development.js:3991
dispatchEventForPluginEventSystem @ react-dom.development.js:9287
dispatchEventWithEnableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay @ react-dom.development.js:6465
dispatchEvent @ react-dom.development.js:6457
dispatchDiscreteEvent @ react-dom.development.js:6430

 

어떤 상황에서 저 에러가 발생한 것이냐면,

closeMakeLetter.jsx 파일에 state를 초기화하는 함수를 만든 후,

 

//closeMakeLetter.jsx
import { useSetRecoilState } from "recoil";
import { modalLetterState, writeLetterState } from "@states/ModalState";

export function closeMakeLetter()
{
	const setLetterOpen = useSetRecoilState(modalLetterState);
  const setWriteLetter = useSetRecoilState(writeLetterState);

  const closeMakeLetter = () => {
    setLetterOpen({ isOpen: false, page: 1 });
    setWriteLetter({ color: 0, to: "", message: "", from: "" });
  };
}

 

example.jsx 에서 import 한 후, close 이미지가 클릭되었을 때 그 함수가 실행되도록 onClick 에 넣어주었다.

 

//example.jsx
import * as closeMakeLetter from "components/example"

const example() => {
	return (
		<div>
			<img className="w-[30px] m-2"
        src={closeImage}
        onClick={() => closeMakeLetter.closeMakeLetter()}
        alt="close button"
      />
		</div>
	)
}

 

‘Hooks can only be called inside of the body of a function component.’

 

에러를 잘 읽어보니, hook 에는 컴포넌트 내부에서 작성된 함수만 호출할 수 있는 듯 하다!

결국 원복한 후 에러는 해결되었지만, 이런 상황에서는 반복되는 코드를 해소할 수 있는 다른 방법이 없는지 찾아봐야겠다.

반응형