코딩/리액트

[새싹 성동 2기] React에서 Hooks (useState와 useEffect) 사용하기

insu90 2024. 11. 19. 19:13

React는 함수형 컴포넌트에서도 클래스형 컴포넌트에서 제공하던 상태 관리 및 라이프사이클 기능을 사용할 수 있도록 Hooks를 도입했습니다. 이번 블로그 글에서는 useStateuseEffect 훅을 사용하여 상태 관리와 사이드 이펙트를 처리하는 방법을 설명하고, 이를 통해 실용적인 예제를 구현해보겠습니다.

1. useState: 상태 관리

React에서 함수형 컴포넌트는 상태(state)를 관리하기 위해 useState 훅을 사용합니다. useState는 상태 변수의 초기값과 이 값을 업데이트할 수 있는 함수를 반환합니다. 형태는 아래와 같습니다.

const [ 상태변수의 초기값, 상태변수의 값을 변경하는 함수 ] = useState;

예제: 사용자 이름과 별명을 관리하는 컴포넌트

먼저, 사용자 이름과 별명을 입력받아 관리하는 Info 컴포넌트를 만들어보겠습니다.

src 디렉터리 아래에 사용자 이름과 별명을 관리하는 Info.js 파일을 생성

import { useState } from "react";

function Info() {
    // 상태 변수를 정의
    const [name, setName] = useState('');  // name 상태 변수
    const [nickname, setNickname] = useState('');  // nickname 상태 변수

    // 상태 변수의 값을 변경하는 이벤트 핸들러 함수 정의
    const changeName = e => setName(e.target.value);
    const changeNickname = e => setNickname(e.target.value);

    return (
        <>
            <div>
                <p>이름: {name}</p>
                <p>별명: {nickname}</p>
            </div>
            <div>
                <p>이름: <input type="text" name="name" value={name} onChange={changeName} /></p>
                <p>별명: <input type="text" name="nickname" value={nickname} onChange={changeNickname} /></p>
            </div>
        </>
    );
}

export default Info;

핵심 포인트:

  • useState를 통해 name과 nickname 상태 변수를 선언하고, 이 값을 변경할 수 있는 setName과 setNickname 함수를 받습니다.
  • 입력 필드에서 값을 변경하면 onChange 이벤트를 통해 상태 변수를 업데이트합니다.

App.js에 컴포넌트 추가

App.js에 Info 컴포넌트를 추가하여 실제로 렌더링되는 모습을 확인할 수 있습니다.

import Info from "./Info";

function App() {
  return (
    <Info />
  );
}

export default App;

 

 

2. useEffect: 사이드 이펙트 관리

useEffect 훅은 클래스형 컴포넌트의 componentDidMount, componentDidUpdate, componentWillUnmount를 합친 기능을 제공합니다. 이 훅은 컴포넌트가 마운트되거나 업데이트될 때 특정 작업을 실행하거나, 컴포넌트가 언마운트될 때 정리 작업을 수행할 수 있습니다. 형태는 아래와 같습니다.

useEffect(이펙트 함수, 의존성 배열); 

예제: Info 컴포넌트에서 useEffect 사용하기

import { useEffect, useState } from "react";

function Info() {
    const [name, setName] = useState('');
    const [nickname, setNickname] = useState('');

    const changeName = e => setName(e.target.value);
    const changeNickname = e => setNickname(e.target.value);

    // 의존성 배열을 생략 ⇒ 마운트, 업데이트 모두 이팩트 함수를 실행
    useEffect(() => {
        console.log("렌더링이 완료되었습니다.");
        console.log({ name, nickname });
    });

    return (
        <>
            <div>
                <p>이름: {name}</p>
                <p>별명: {nickname}</p>
            </div>
            <div>
                <p>이름: <input type="text" name="name" value={name} onChange={changeName} /></p>
                <p>별명: <input type="text" name="nickname" value={nickname} onChange={changeNickname} /></p>
            </div>
        </>
    );
}

export default Info;

 

핵심 포인트:

  • useEffect 훅은 컴포넌트가 렌더링된 후 실행됩니다. 여기서는 name과 nickname 상태가 변경될 때마다 로그가 출력됩니다.
  • 의존성 배열을 생략하면 컴포넌트가 마운트될 때뿐만 아니라 상태가 업데이트될 때마다 이펙트가 실행됩니다.

마운트될 때만 실행하도록 수정

컴포넌트가 처음 렌더링될 때만 실행되게 하려면 의존성 배열에 빈 배열 []을 전달합니다.

useEffect(() => {
    console.log("렌더링이 완료되었습니다.");
    console.log({ name, nickname });
}, []);

특정 상태변수의 변경에 반응하기

useEffect는 특정 상태 변수나 props가 변경될 때만 실행되도록 설정할 수 있습니다. 예를 들어, name 상태가 변경될 때만 이펙트를 실행하려면 아래와 같이 작성합니다.

useEffect(() => {
    console.log("렌더링이 완료되었습니다.");
    console.log({ name, nickname });
}, [name]);

상태변수 별로 개별적인 useEffect 설정

useEffect 훅은 여러 개를 사용할 수 있으며, 각 훅은 서로 다른 상태에 반응하도록 설정할 수 있습니다.

useEffect(() => {
    console.log("컴포넌트가 마운트 되었습니다.");
    console.log({ name, nickname });
}, []);

useEffect(() => {
    console.log("name 상태변수가 변경되었습니다.");
    console.log({ name, nickname });
}, [name]);

useEffect(() => {
    console.log("nickname 상태변수가 변경되었습니다.");
    console.log({ name, nickname });
}, [nickname]);

후처리(cleanup) 함수

이펙트 함수에서 후처리 작업을 실행하고 싶다면, 이펙트 함수 내부에서 반환값으로 함수를 정의할 수 있습니다. 이 함수는 컴포넌트가 언마운트되거나 리렌더링되기 직전에 실행됩니다.

useEffect(() => {
    console.log("name 상태변수가 변경되었습니다.");
    console.log({ name, nickname });

    return () => console.log("cleanup", name);
}, [name]);

 

3. 후처리(cleanup) 함수 테스트

App 컴포넌트에 Info 컴포넌트를 보이기/숨기기 하는 버튼을 추가하여 후처리 함수가 어떻게 작동하는지 확인할 수 있습니다.

import { useState } from "react";
import Info from "./Info";

function App() {
  const [isVisible, setIsVisible] = useState(false);
  const changeIsVisible = () => setIsVisible(!isVisible);

  return (
    <>
      <button onClick={changeIsVisible}>{isVisible ? "숨기기" : "보이기"}</button>
      {isVisible && <Info />}
    </>
  );
}

export default App;

언마운트될 때만 cleanup 함수 실행

의존성 배열을 빈 배열 []로 설정하면, 컴포넌트가 언마운트될 때만 cleanup 함수가 실행됩니다.

useEffect(() => {
    console.log("name 상태변수가 변경되었습니다.");
    console.log({ name, nickname });

    return () => console.log("cleanup", name);
}, []);

useStateuseEffect 훅을 사용하여 함수형 컴포넌트에서 상태를 관리하고 사이드 이펙트를 처리할 수 있습니다. 이러한 기능들을 활용하여 클래스형 컴포넌트에서 하던 작업을 간결하고 직관적으로 처리할 수 있으며, React의 함수형 컴포넌트에서 더 많은 기능을 활용할 수 있습니다.

 

*생성형 AI 활용한 클라우드&보안 전문가 양성캠프 과정의 교육내용 정리 자료입니다.