개발 기록/Web

React Hook에 대해서

시유후 2025. 12. 16. 14:36

0

React Hook은 너무 추상적인 내용이라고 생각했다. 어딜가나 이게 어떤 역할을 하고, 어떤 규칙이 있고 이런 상세 내용은 알려주는 글은 많이 봤는데, 정확하게 이게 뭔지 정의하는 문구가 없었다. 리액트를 참 오래 써왔지만, 최근까지도 왜 Hook이 이런식으로 생겼는지, 왜 쓰는지 모르고 감각적으로 써왔다.

1

Hook을 이해하려면 과거로 돌아가야한다. 현재의 React가 아닌 Hook이 도입되기 이전 16.8버전 이전으로. 현대의 리액트 컴포넌트는 대부분 Functional Component로 만들어진다. 지금까지 와서야 Class Component를 쓰는곳은 레거시(16.8버전 이전) 전환이 끝나지 않은 곳 뿐이지 않을까. 그 시절에는 useState, useEffect같은 hook이 없었기에 functional Component를 쓰기 어려웠다. Class Component에는 강력한 도구인 state 와 React Lifecycle을 활용할 수 있는 componentDidMount 와 같은 함수들이 있었다.

2

이를 사용할 수 있게 만들어준것이 바로 React Hook이다. Functional Component 에서도 React의 기반인 state와 lifecycle을 사용할 수 있게 건져올린(Hook) 것이다.

// 이젠 잘 기억도 안나는 class Component..
class Tags extends React.Component {
    contructor(props) {
        super(props)
        this.state = {tagString: 'None'};
    }

    changeText(str: string) {
        this.setState({
            tagString: str
        });
    }

    componentDidMount() {
        this.changeText('Mounted!')
    }

    componentDidUpdate() {
        console.log('tagString is updated')
    }

    compoenentWillUnmount() {
        console.log("I'll Die...");
    }

    render() {
        return (
            <div>{this.state.tagString}</div>
        )
    }
}

useState와 useEffect를 사용하면 위 Class Component를 다음과 같이 간결하게 표현할 수 있다. 코드를 보며 주석을 통해 각 기능이 어떻게 대체되었는지 확인해보자.

export function Tags(props) {
    // 1. this.state와 this.setState를 대체
    const [tagString, setString] = useState('None');

    // 2. componentDidMount 대체
    // 의존성 배열([])이 비어있으므로 마운트 시 1회만 실행됨
    useEffect(() => {
        setString('Mounted');

        // 3. componentWillUnmount 대체
        // 컴포넌트가 사라질 때(Unmount) 실행되는 cleanup 함수
        return () => {
            console.log("I'll Die...");
        };
    }, []);

    // 4. componentDidUpdate 대체
    // tagString이 변할 때마다 실행됨
    useEffect(() => {
        console.log('tagString is updated');
    }, [tagString]);

    return <div>{tagString}</div>;
}

자세한 LifeCycle에 대한 설명은 아래 두 사이트를 참고.
첫 번째는 class Component, 두번째는 Functional Component입장에서의 Lifecycle.
https://ko.legacy.reactjs.org/docs/react-component.html https://ko.react.dev/learn/lifecycle-of-reactive-effects

[React.Component – React

A JavaScript library for building user interfaces

ko.legacy.reactjs.org](https://ko.legacy.reactjs.org/docs/react-component.html)

[React Effect의 생명주기 – React

The library for web and native user interfaces

ko.react.dev](https://ko.react.dev/learn/lifecycle-of-reactive-effects)

3

Custom Hook이란 다른 hook을 사용하고, convention이 지켜진 하나의 함수이다.

  • use로 시작하는 함수일것.
  • 함수 내 다른 Hook을 호출하여 사용할것.

그래서 대표적인 예시인 타이머 예시가 나온다. 아래 예제는 React의 state와 lifecycle을 react 기반으로 부터 꺼내와(hook) 사용하는 custom hook 예제이다.

export const useTimer = () => {
    const [timer, setTimer] = useState(10)

    useEffect(() => {
        const interval = setInterval(() => {
            setTimer(prev => {
                if (prev <= 1) {
                    clearInterval(interval);
                    return 0;
                }
                return prev - 1;
            });
        }, 1000);

        return () => clearInterval(interval);
    }, []);

    return {timer}
}

export const Timer = () => {
    const {timer} = useTimer();

    if(timer < 1) return <div>Time up!</div>

     return <div>{timer}</div>
}

4

이제야, React Hook을 정의할 수 있게 되었다. React Hook이란, React의 state, lifecycle, 그리고 렌더링 과정과 연결된 기능을 Functional Component에서도 사용하기 위해 React core에서 꺼내온(hook) 기능 이다. React의 중요 기능에 대한 정의조차 내리지 못하고 있던 나를 반성하며, 이 정의에서 파생되는 개념들을 설명하기 위한 글을 추가적으로 작성하고자 한다. lifecycle, state, virtual DOM 모두 아직 한 문장으로 정의하기는 아직은 어렵다.