본문 바로가기
프론트엔드/React

[React] hook이 무엇인가요? (생명주기, useEffect, 프론트엔드 기술 면접)

by JI NY 2025. 9. 30.

[React] hook이 무엇인가요? 

프론트엔드 개발자 기술 면접, Hook, useEffect, 라이프싸이클, 생명주기

 

 

🤔 Q. React Hook에 대해 설명해주세요.

💡 A. 답변

hook이란 함수형 컴포넌트에서 상태 관리라이프싸이클 제어를 가능하게 해주는 기능입니다.
즉, 클래스 컴포넌트의 기능을 함수형 컴포넌트에서도 쓰게 해주는 도구이며, 항상 use로 시작합니다.
  • useState : 상태 관리
  • useEffect : 사이드 이펙트 관리
  • useContext : 전역 상태 공유
  • useReducer : 복잡한 상태 업데이트 로직 관리
  • useMemo / useCallback : 성능 최적화

🤔 Q. 그렇다면 hook이 필요한 이유가 무엇인가요?

💡 A. 답변

예전에는 함수형 컴포넌트는 단순히 props만 받아서 렌더링 할 수 있었고, 상태를 가질 수 없었으므로 무조건 클래스형 컴포넌트를 사용해야 했습니다. 하지만이 나오면서 상태 관리, 라이프 싸이클 관리, 성능 최적화, 전역 상태 공유 등을 구현할 수 있게 되었습니다. 즉 클래스형 컴포넌트의 불편함을 해소하면서도 클래스형 컴포넌트의 기능을 사용할 수 있기 때문에 hook을 사용합니다.

01. React hook이란?

React Hook이란 React  v16.8에 도입된 기술로, 함수형 컴포넌트에서 state 관리와 Life cycle을 다룰 수 있게 해주는 기술입니다.

 

1.1. React hooks는 왜 도입되었을까?

기존의 리액트는 클래스 기반의 컴포넌트로 작업했습니다. 하지만 클래스 컴포넌트에는 몇 가지 불편함이 존재했습니다.

 

1. this 값이 변경될 수 있습니다.

- this는 클래스 자신을 가리키지만, this가 가리키는 값은 변경이 될 수 있기 때문에 컴포넌트가 리렌더링 되면서 문제가 발생할 수 있습니다. 

 

2. 재사용성 문제가 있습니다.

- 클래스 컴포넌트에서 상태 로직을 재사용하기가 쉽지 않았습니다. HOC 패턴과 같은 방법으로 해결하고자 했지만, 또 HOC에는 또 다른 문제가 발생했습니다.

 

3. 기존의 함수형 컴포넌트

- 이 당시 함수형 컴포넌트가 존재하기는 했지만, 렌더링 기능만 존재했습니다.

- 하지만 hooks가 생긴 이후, 상태 관리, 생명 주기 기능 등을 함께 이용할 수 있게 되면서 기존의 클래스형 컴포넌트에서 함수형 컴포넌트로 사용하게 되었습니다.

 


02. Hooks로 얻는 이점 

2.1. class형에 비해 더 깔끔하고 간단한 코드를 작성할 수 있습니다.

※ Count를 1 증가시키는 버튼이 있는 코드 예시

왼쪽 코드는 클래스형 컴포넌트, 오른쪽 코드는 함수형 컴포넌트 예시입니다.

코드 가독성이 더 좋아진 것을 알 수 있습니다.

 

 

 

2.2. 라이프 싸이클 사용 방식이 간단해졌습니다.

출처 : https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/

※ 라이프 싸이클이란?

리액트 컴포넌트는 마운트(mount, 탄생) => 업데이트(update) => 언마운트(unmount, 소멸)의 3 단계 과정이 있습니다. 이를 라이프 싸이클이라고 합니다.

즉, componentDidMount() -> componentDidUpdate -> componentWillUnmount() 순으로 클래스형 컴포넌트의 라이프 싸이클 함수가 진행됩니다.

 

1. Mount : 컴포넌트는 화면에 추가될 때 마운트 됩니다.

- 처음 컴포넌트가 생성되고 렌더링을 거치는 과정입니다. 

- Mount가 끝나면 componentDidMount() 함수를 실행합니다.

 

2. Update : 컴포넌트는 일반적으로 상호작용에 대한 응답으로 새로운 props나 state를 수신하면 업데이트 됩니다.

-  forceUpdate() : 강제로 리렌더링 일으키는 메소드

-  클래스 컴포넌트에서 업데이트가 끝나고 componentDidUpdate() 를 실행합니다.

 

3. Unmount : 컴포넌트가 화면에서 제거되면 마운트가 해제됩니다.

- 컴포넌트가 종료되는 과정으로서, componuntWillUnmount() 함수를 실행합니다.

 

이러한 과정으로 클래스형 컴포넌트 생명주기를 가졌었는데, useEffect() hook을 사용하면 함수 한 개로 모두 한 번에 사용할 수 있습니다.

 


2.2.1. 간단한 라이프 싸이클 사용 hook 예시 : useEffect()

기존 componentDidMount() -> componentDidUpdate() -> componentWillUnmount() 순으로 클래스형 컴포넌트의 라이프 싸이클 함수가 진행되는데, 이를 useEffect() 함수 (hook) 하나로 사용할 수 있습니다. 

 

※ useEffect()란?

특정한 상황에서 사이드 이펙트를 실행시킬 수 있는 hook입니다.

import { useEffect } from "react";

function MyComponent() {
  useEffect(() => {
    // 이 안에 실행하고 싶은 코드를 작성
    console.log("컴포넌트가 렌더링될 때마다 실행");

    // cleanup 함수(optional)
    return () => {
      console.log("컴포넌트가 언마운트 되거나 effect가 재실행될 때 실행");
    };
  }, []); // 의존성 배열
}

 

    • 첫 번째 인자: 사이드 이펙트를 실행할 콜백함수
      • 이펙트 함수는 렌더링 이후 실행되는 함수입니다. 이펙트 함수의 반환값으로 콜백함수가 있다면 컴포넌트가 언마운트 될 때 실행됩니다. 이때 실행되는 콜백 함수를 '클린업 함수'라고 합니다.
    • 두 번째 인자: 의존성 배열 (dependencies)
      • [] → 컴포넌트 마운트 시 한 번만 실행
      • [value] → value가 바뀔 때마다 실행
      • 생략 → 렌더링 될 때마다 실행

 

 

2.3. Hook을 이용했을때의 재사용성의 이점 

hook 재사용성의 이점을 설명하기 전, 클래스형 컴포넌트에서 상태로직을 재사용하기 어려운 이유를 설명드리겠습니다.

 

 

2.3.1.  클래스형 컴포넌트에서 상태로직을 재사용하기 어려운 이유 

 

1. 상태 로직이 생명주기에 강하게 묶여 있기 때문입니다. 

- 클래스형 컴포넌트에서는 상태를 this.state, this.setState로만 관리할 수 있고, 부수 효과(데이터 fetch, DOM 조작 등)는 componentDidMount, componentDidUpdate, componentWillUnmount 같은 생명주기 메서드에 흩어져 있습니다.

- 따라서 하나의 상태 관련 로직이 여러 메소드에 흩어지기 때문에 이를 잘라내어 다른 컴포넌트에서 재사용하기가 어렵습니다.

- 아래는 예시 코드에며, 관련 로직이 세 군데로 흩어져 있는 것을 확인할 수 있습니다.

class Example extends React.Component {
  componentDidMount() {
    // 구독 시작
  }
  componentDidUpdate(prevProps) {
    // 조건에 따라 구독 갱신
  }
  componentWillUnmount() {
    // 구독 해제
  }
}



 

2. 고차 컴포넌트(HOC) 패턴 등을 이용하여 로직을 재사용해야 합니다.

- 클래스형에서는 주로 HOC(High Order Component) 패턴 등을 이용하여 로직을 재사용합니다. 

- 하지만, HOC 패턴은 Wrapper 지옥라는 큰 문제가 있었습니다. 예를 들어 임의의 컴포넌트가 있을 때, 해당 컴포넌트에 여러 로직을 추가하고 싶은데 그렇게 하기 위해서는 고차 컴포넌트가 계속 감싸지게 되면서 결국 Wrapper 지옥에 빠지게 된다는 문제입니다.

사진 출처 : https://medium.com/@jackyef/react-hooks-why-we-should-embrace-it-86e408663ad6

 

※ HOC란?

- 화면에서 재사용 가능한 로직을 분리해서 컴포넌트로 만들고 (userHOC라는 고차 컴포넌트로 생성), 재사용 불가능한 부분은 parameter로 받아서 처리하는 방법입니다.

- 아래 코드와 같이 사용자의 나이 정보 페이지, 직업 정보 페이지를 나타내는 코드 예시로 설명드리겠습니다. 

- 2개의 컴포넌트는 렌더링 하는 부분만 조금 다르고, fetching 하는 부분은 같은 것을 알 수 있습니다. 이 중복된 코드를 클래스 컴포넌트에서 재사용성 있게 바꾸려면, usersHOC라는 고차 컴포넌트를 제작하면 됩니다.

 

- 그렇게 만든 userHOC 고차 컴포넌트아래와 같습니다. 

왼쪽 코드와 같이, 중복된 부분을 고차 컴포넌트로 만들고 인자로 Component를 받습니다.

인자로 받은 Component를 render()에 넣어서 컴포넌트의 props유저 state를 전달하도록 만들면 됩니다.

오른쪽 코드와 같이, 각 페이지에서는 이런 userHOC 고차 컴포넌트를 감싸서 사용하면 됩니다.

 

 

 

2.3.2. Hooks가 등장한 이후, 재사용성 문제 해결 

- Hook이 등장한 이후, 함수형 컴포넌트의 Custom Hook을 사용해서 재사용성 문제를 해결할 수 있게 되었습니다.

 

※ 커스텀 훅이란?

- 개발자가 직접 만든 hook으로, 반복되는 메소드를 하나로 묶어 사용하는 것입니다. 

- 보통 Input과 Fetch를 관리할 때 자주 쓰입니다.

- 커스텀 훅의 이름은 use로 시작해야 합니다.

 

- 위의 UserHOC 로직을 Hook으로 만들면 아래와 같습니다. (useFetchUser)

const useFetchUser = () => {
	const [users, setUsers] = useState([]);
  	
  	useEffect(() => {
    	fetchUsers().then(users => {
        	setUsers(users);
        })
    },[])
  
  	return users;
}

- 이렇게 한다면, 그냥 호출만 하면 되므로 Wrapper 지옥 문제가 발생되지 않게 됩니다.

const UserAgePage = () => {
	const users = useFetchUser();
    
    return (
    	<div>
        ... 
	
}

 


03. 요약

1. React Hook이란? 

- 함수형 컴포넌트에서 state 관리와 Life Cycle을 다룰 수 있게 하는 기술입니다.

 

2. Hooks의 도입 이유는?

- 클래스형 컴포넌트에서 발생하는 불편한 점들을 극복하기 위해서 도입되었습니다.

 

3. Hooks의 이점은?

- 클래스형 컴포넌트에 비해 깔끔하고 간결한 코드를 작성할 수 있으며, 재사용성을 높일 수 있습니다. 


참고자료

https://despiteallthat.tistory.com/301

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

https://ko.react.dev/reference/react/useEffect

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

https://velog.io/@hyeon9782/10%EB%B6%84-%ED%85%8C%EC%BD%94%ED%86%A1-React-Hooks

https://www.youtube.com/watch?v=qjEcsNYFWYg

(HOC 부분은 10분 테코톡 코드를 활용했습니다.)

https://medium.com/@jackyef/react-hooks-why-we-should-embrace-it-86e408663ad6

https://velog.io/@niboo/React-Custom-Hook-%EC%9D%B4%EB%9E%80


읽어주셔서 감사합니다~

도움이 되셨다면 공감 부탁드립니다 😊

직접 공부하며 정리한 내용이어서 틀릴 수도 있습니다. 피드백 환영입니다!

 

 

댓글