Front-end/React

[React] React Hook "~" cannot be called inside a callback 오류, 리액트 커스텀 훅과 일반 공통 함수의 차이

냐옹멍멍 2024. 3. 7. 17:30
반응형

# 이슈

리액트 환경에서 커스텀 훅, 또는 공통 함수가 필요한 경우가 더러 있다.

커스텀 훅이란 리액트에서 사용하는 훅들 (use~ 이름의 함수들)을 제외한 사용자 정의 함수인데,

 

개인적으로는 쉽게 공통함수와 비슷한 결로 이해하고 있었다.

그리고 이렇게 이해한 게 문제였다,,

 

문제 해결 부분만 보고 싶으신 분들은 아래 #방안 부터 읽으시면 됩니다.


 

문제가 발생한 순서는 이렇다.

  1. 일부 페이지에서 id값을 받아 특정 텍스트로 변환하는 함수가 필요함
  2. 공통 함수만 만들면 되겠다!
  3. 커스텀 훅이 공통 함수인가? 이걸로 해보자

물론 커스텀 훅은 공통함수가 맞지만, 반대의 경우는 성립되지 않는다.


 

문제의 코드이다.

export default function useFuction() {
  // 공통 함수 내용
  return 1;
}

 

이제 이 함수를 불러와 사용해 보자

import useFunction from "../hooks/useFunction"

...

useEffect(() => {
  let resFunction = useFunction(); // 사용 위치
  console.log(resFunction);
},[])

...

 

오류를 뱉는다.

React Hook "useFunction" cannot be called inside a callback. 
React Hooks must be called in a React function component or a custom React Hook function

 

커스텀 훅 사용방식에 문제가 있다고 한다.

오류 내용이 리액트에 약한 나를 더 헷갈리게 했다.

 

그저 use이름이 붙은 함수를 공통으로 뺐을 뿐인데 훅이 된다?

이 오류로 인해 Hook == common function이라는 생각을 가졌었다.

 

커스텀 훅 관점에서 이 코드의 문제는 공식문서에서 확인할 수 있다.

 

 

 

그럼 최상위 레벨에서 함수를 받아 다시 사용하면 되겠네?

 

 

 

그런 줄 알았지. 실제로 그러니 되더라.

export default function Home() {
  const newFunction = useFunction;
  ...
}

 

한동안 이렇게 사용했는데, 아무리 생각해도 이상했다.

 

공통 함수를 만들어 export 하고 사용할 컴포넌트에서 import 하기만 하면 되는

이 간단한 작업을 이렇게 불편하게 해야 하나?

 


 

# 방안

방안도 공식 문서에서 확인할 수 있었다.

공식문서를 잘 읽도록 하자...

 

React 컴포넌트와는 다르게 사용자 정의 Hook은 특정한 시그니처가 필요 없습니다. 무엇을 인수로 받아야 하며 필요하다면 무엇을 반환해야 하는 지를 사용자가 결정할 수 있습니다. 다시 말하지만, 보통의 함수와 마찬가지입니다. 이름은 반드시 use로 시작해야 하는데 그래야만 한눈에 보아도 Hook 규칙이 적용되는지를 파악할 수 있기 때문입니다.

 

이 외에도 Create React App을 통해 설치한 경우

리액트에 맞는 규칙을 검사하는 ESLint 플러그인이 기본으로 추가된다고 한다.

이를 통해 use~ 가 붙은 경우 Hook으로 취급하는 것 같은데..

 

확인을 위해 useFunction에서 이름을 function(가칭)으로 바꾸니 실제로 오류가 사라졌다.

 

# 결론

  • use가 붙은 경우 Hook으로 취급하며 Hook규칙에 맞게 작성, 사용돼야 함 (최상위에서만 사용 가능)
  • 일반 공통 함수인 경우 제약 없이 사용가능

 

# 참고

https://ko.legacy.reactjs.org/docs/hooks-rules.html

반응형