React Hook "useRef" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return? 오류

박영광·2023년 12월 11일
0

React

목록 보기
5/23

클릭을 했을때 log가 찍히는
App.js에선

const sayHello =  () => console.log("say hello");
const title = UseClick(sayHello);
//UseClick

 <h1 ref={title}>Hi! Click me</h1>

을 만들고자 할 때

useClick.js 컴포넌트는 밑의 코드와 구성했을 시

import { useState, useEffect, useRef  } from "react"

const UseClick  = onClick => {
    if (typeof onClick !== "function"){
        return;
    }
    const element = useRef();
    useEffect(() => {
        if(element.current) {
            element.current.addEventListener("click", onClick);
        }
        return () => {
            if (element.current) {
                element.current.removeEventListener("click", onClick);
            }
        };
    }, []);
    return element;
};


export default UseClick ;

src\component\useClick.js
Line 7:21: React Hook "useRef" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return? react-hooks/rules-of-hooks 란 오류가 발생했다.

이 오류는 검색해보니
React Hook 규칙에 따라서 발생하는 것이었다.
React Hooks는 항상 컴포넌트의 최상위 레벨에서 호출되어야 하며, 조건문 안이나 루프 안에서 호출되어서는 안 된다. 하지만 현재 코드에서는 useRef와 useEffect 훅이 조건문 안에서 호출되고 있어서 이 오류가 발생하고 있었던 것이었다.

해결하기 위해서는 조건문 바깥에서 useRef와 useEffect를 호출하도록 코드를 변경해야 했다.

import { useEffect, useRef } from "react";

const UseClick = (onClick) => {
  const element = useRef();

  useEffect(() => {
    if (typeof onClick !== "function") {
      console.warn("onClick should be a function");
      return;
    }

    const handleClick = (event) => {
      onClick(event);
    };

    if (element.current) {
      element.current.addEventListener("click", handleClick);
    }

    return () => {
      if (element.current) {
        element.current.removeEventListener("click", handleClick);
      }
    };
  }, [onClick]);

  // 올바른 방법: ref를 반환하지 말고, 직접 element를 반환
  return element;
};

export default UseClick;

클릭했을 때 문제없이 콘솔이 찍히는 것을 알 수 있었다.
따라서 코드를 이와 같이 수정했다:

profile
매일 1mm씩 성장하겠습니다

0개의 댓글