본문 바로가기
  • 삽질하는 자의 블로그
React/React-Basic

9. 훅의 사용 유의사항과 커스텀 훅에 대하여

by 이게뭐당가 2022. 12. 14.

중복되는 함수 및 중복되는 코드가 있을때, helper(나는 이렇게 지었다) 폴더 안에 넣어둔 파일안에 넣고,

"아웃소싱" 을 하는 [ 코드 리팩토링 ]  을 하여, 깔끔한 상태를 유지하려 한다.

 

리팩토링을 하고 싶은데, 그 안에 Hook 이 들어있다면?

 

"Hook 이 포함된 상태의 함수"를 리팩토링해야한다.

 

이때, Hook 을 포함하는 리팩토링 코드를, "커스텀 훅" 이라고 한다.

 

1. 훅을 아웃소싱?

 

훅의 사용 유의사항을 보자

 

    <훅 사용의 유의사항>
    
        1. HOOK 은 반드시 "리액트 컴포넌트 함수"안에서 사용해야한다. 
        리액트 컴포넌트 밖에 정의한 "리듀서 함수", "next의 SSR", "API" 등.. 다른곳은 안된다.

        2. HOOK 은 반드시, "컴포넌트 함수의 최상위에 사용해야한다"
        콜백 함수, 중첩 함수 같은, 하위 블록의 함수에서 사용이 불가능하다.

훅은 반드시, "리액트 컴포넌트 함수" 안에서만 사용해야한다 했다. 그런데 어떻게 "커스텀훅"을 만들지?

 

2. 커스텀 훅을 만들기

 

리액트는, use 로 시작되는 모든 것을 Hook 으로 취급하려는 성질을 가진다.

그러므로, 훅이 포함된, 코드를 리팩토링 할 때, use 로 시작되는 함수로 만들어야한다.

 

  <규칙> ***
        "반드시!!" 리팩토링 하는 함수의 이름을 "use" 로 시작하게 만든다.

            function use... ( O ) 
            function useCounter ( O ) 
            function useAdd ( O ) 

            function refactoringHook ( X )

        "그래야만, 리액트가 확인하고, 커스텀훅으로 인정된다."

 

3. 간단한 커스텀 훅 만들기

 

여기, 비슷하지만 다른, 훅이 포함된 코드가 존재한다.

 

<컴포넌트 1>

   import {useState, useEffect} from "react"

    function ...(){
        const [counter, setCounter] = useState(0)

        useEffct(()=>{
            const interval = setInterval(()=>{
                setCounter((prev)=>(prev +1))       // 차이점 : +1 이됌
            }, 1000)

            retrun ()=> clearInterval(interval)
        },[])

        return (
            <div> {counter} </div>
        )
    }

<컴포넌트 2>
    import {useState, useEffect} from "react"

    function ...(){
        const [counter, setCounter] = useState(0)

        useEffct(()=>{
            const interval = setInterval(()=>{
                setCounter((prev)=>(prev -1))       // 차이점 : -1 이됌
            }, 1000)

            retrun ()=> clearInterval(interval)
        },[])

        return (
            <div> {counter} </div>
        )
    }

이 함수가 "수백개" 가 있다고 가정한다면, 일일이 하나씩 쓰는것은 불가능에 가깝다. 알아보는것도 마찬가지

 

그러므로, hooks 폴더 안에 커스텀 훅을 만들어서, 리팩토링한다.

 

<커스텀훅>

    "/hooks/use-counter.js"

	import {useState, useEffect} from "react"
        
        function useCounter(){                          // 반드시 use 로 시작할것
            const [counter, setCounter] = useState(0)   // 훅 사용을 그대로 복사

            useEffct(()=>{
                const interval = setInterval(()=>{
                    setCounter((prev)=>(prev -1))       
                }, 1000)
                retrun ()=> clearInterval(interval)
            },[])

            return counter;                             // "상태"를 반환 ***
        }   
        export default useCounter                       // export 한다.
       1. 커스텀 훅은 use 로 시작한다.

       2. 커스텀 훅은 커스텀 훅 내부의 상태를 반환하여, 전달한다.

       3. 커스텀 훅에서 "내부의 값" 을 외부로 사용하려면 그 모든 것들은 "return" 을 통해 반환해야한다.

    ** 4. 만약 [ 커스텀 훅  안의 함수] 에서 나온 값으로, 외부(사용하는 곳)에서 사용하고 싶다면

       	커스텀 훅 내부에서, 함수를 만들고 그 안에 나온 값을 파라미터로 만들어서 사용 가능하다.

 

4. 간단한 커스텀 훅의 사용

 

<컴포넌트 1>

   import useCounter from "./hooks/use-counter.js"

    function ...(){
        const counter = useCounter()

        return (
            <div> {counter} </div>
        )
    }

 

5.  커스텀 훅과 매개변수

 

위의 커스텀 훅은, 이미, 하드코딩된 코드를 가지고 있기에, "재사용" 이 거의 불가능하다.

 

재사용이 가능하도록, 매개변수를 사용해보자

 

<커스텀훅>
    "/hooks/use-counter.js"

        function useCounter( forward = true ){           // 매개변수 설정 후 초기값 부여
            const [counter, setCounter] = useState(0)          
            useEffct(()=>{
                if(forward){
                    const interval = setInterval(()=>{
                        setCounter((prev)=>(prev +1))       // 매개변수 에 따라 바뀌는 함수
                    }, 1000)
                } else{
                    const interval = setInterval(()=>{
                        setCounter((prev)=>(prev -1))       // 매개변수 에 따라 바뀌는 함수
                    }, 1000)
                }
                retrun ()=> clearInterval(interval)
            },[counter])
            return counter;
        }   
        export default useCounter

 

 

댓글