본문 바로가기

쉽게 배우는 리액트 프로그래밍

리액트 프로그래밍: 훅으로 지역 상태 관리 마스터하기!

반응형

리액트 컴포넌트에서 데이터를 효율적으로 관리하는 방법은 뭘까요? 🤔 컴포넌트 내부에서만 사용되는 데이터, 즉 지역 상태를 어떻게 다루고, 변경 사항을 반영해야 할까요?

바로 리액트의 핵심 기능 중 하나인 훅(Hook)을 이용하면 됩니다! 특히, useStateuseEffect 훅은 함수형 컴포넌트에서 지역 상태를 관리하는 데 핵심적인 역할을 하죠. 이 글에서는 리액트 훅을 사용하여 지역 상태를 어떻게 효과적으로 관리할 수 있는지 자세히 알아보고, 몇 가지 유용한 팁도 함께 살펴볼 거예요.

리액트 훅을 활용한 지역 상태 관리: 기본 개념부터 활용까지

리액트 훅은 함수형 컴포넌트에서 상태 및 생명 주기 기능을 사용할 수 있도록 해주는 아주 유용한 도구에요. 굳이 클래스 컴포넌트를 사용하지 않고도 함수형 컴포넌트에서 상태를 관리하고, 컴포넌트의 생명 주기에 따라 특정 작업을 실행할 수 있도록 지원해주죠.

1. 지역 상태: 컴포넌트의 독립적인 데이터 저장소

리액트 컴포넌트는 각자의 역할을 수행하기 위해 독립적인 데이터를 관리해야 할 때가 많아요. 예를 들어, 특정 버튼을 클릭할 때마다 카운트를 증가시키거나, 입력 필드에 값을 입력받아 저장하는 경우가 있겠죠? 이러한 컴포넌트 내부에서만 사용되는 데이터를 지역 상태라고 부릅니다.

지역 상태는 해당 컴포넌트가 렌더링될 때 초기화되고, 컴포넌트 외부(부모 컴포넌트 등)와는 독립적으로 관리됩니다. 즉, 부모 컴포넌트에서 지역 상태에 직접 접근하거나 변경할 수 없어요. 이를 통해 컴포넌트 간의 의존성을 줄이고, 컴포넌트를 재사용하기 쉽게 만들어줍니다. 지역 상태 관리를 통해 코드의 복잡성을 줄이고 유지보수성을 높일 수 있죠.

2. useState 훅: 컴포넌트 상태 관리의 핵심

컴포넌트의 상태를 선언하고 업데이트하는 데 사용되는 가장 기본적인 훅이 바로 useState입니다. useState 훅을 사용하면 컴포넌트 내부에서 상태 변수를 선언하고, 이 변수의 값을 변경할 수 있는 함수를 함께 얻을 수 있어요.

간단한 예시를 통해 살펴볼까요?

import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0); // count라는 상태 변수를 0으로 초기화

  return (
    <div>
      <p>You clicked {count} times</p> 
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

export default Counter; 

위 코드에서 useState(0)count라는 상태 변수를 0으로 초기화하고, setCount 함수를 통해 이 변수를 업데이트할 수 있게 해줍니다. 버튼을 클릭할 때마다 setCount(count + 1)을 호출하여 count 상태를 1씩 증가시키고, 컴포넌트가 다시 렌더링되면서 화면에 업데이트된 값이 표시됩니다.

3. useEffect 훅: 컴포넌트 생명 주기 관리

useEffect 훅은 컴포넌트의 생명 주기와 관련된 작업을 처리하는 데 사용됩니다. 컴포넌트가 마운트될 때, 업데이트될 때, 언마운트될 때 등 특정 시점에 특정 작업을 실행하도록 설정할 수 있죠.

예를 들어, 컴포넌트가 마운트될 때 API 호출을 하고, 언마운트될 때 타이머를 해제하는 작업을 수행할 수 있어요.

import React, { useEffect, useState } from 'react';

function DataFetchingComponent() {
  const [data, setData] = useState(null);

  useEffect(() => {
    const fetchData = async () => {
      const response = await fetch('/api/data'); 
      const jsonData = await response.json();
      setData(jsonData);
    };

    fetchData(); 

    return () => { 
      // 컴포넌트가 언마운트될 때 실행될 작업 (청소 작업)
      console.log('데이터 가져오기 작업이 취소되었습니다.');
    };
  }, []); // 빈 배열은 컴포넌트가 마운트될 때만 useEffect를 실행하도록 설정 
  
  return (
    <div>
      {data ? (
        <ul>
          {data.map((item) => (
            <li key={item.id}>{item.name}</li>
          ))}
        </ul>
      ) : (
        <p>데이터를 가져오는 중입니다...</p>
      )}
    </div>
  );
}

export default DataFetchingComponent;

위 코드에서 useEffect 훅은 컴포넌트가 마운트될 때 fetchData 함수를 호출하여 API 데이터를 가져오고, setData 함수를 사용하여 data 상태를 업데이트합니다. 또한, return 문에서 컴포넌트가 언마운트될 때 실행될 작업(예: 데이터 가져오기 작업 취소)을 정의할 수 있습니다.

4. useCallback 훅: 콜백 함수 최적화

useCallback 훅은 특정 의존성이 변경될 때만 콜백 함수를 새로 생성합니다. 이를 통해 불필요한 렌더링을 방지하고 성능을 향상시킬 수 있죠.

다음 예시를 살펴볼까요?

import React, { useState, useCallback } from 'react';

function ParentComponent() {
  const [count, setCount] = useState(0);

  const handleClick = useCallback(() => {
    setCount(count + 1);
  }, [count]); // count가 변경될 때만 handleClick 함수를 재생성

  return (
    <div>
      <h1>Parent Component</h1>
      <p>Count: {count}</p>
      <ChildComponent onClick={handleClick} /> 
    </div>
  );
}

function ChildComponent({ onClick }) {
  return (
    <div>
      <h2>Child Component</h2>
      <button onClick={onClick}>Increment</button>
    </div>
  );
}

위 코드에서 handleClick 함수는 count 상태가 변경될 때만 새로 생성됩니다. 만약 useCallback을 사용하지 않으면, ParentComponent가 렌더링될 때마다 handleClick 함수가 새로 생성되어 불필요한 렌더링이 발생할 수 있습니다.

5. useMemo 훅: 값 계산 최적화

useMemo 훅은 특정 값을 계산하는 과정을 최적화하는 데 사용됩니다. 복잡한 계산이나 값 변환이 필요한 경우, useMemo 훅을 사용하면 해당 값이 필요할 때만 계산되도록 하여 성능을 향상시킬 수 있습니다.

예를 들어, 큰 배열을 필터링하거나 정렬하는 작업을 수행하는 경우, useMemo 훅을 사용하여 결과 값을 캐싱할 수 있습니다.

import React, { useState, useMemo } from 'react';

function LargeArrayComponent() {
  const [data, setData] = useState([]);

  const filteredData = useMemo(() => {
    return data.filter((item) => item.status === 'active');
  }, [data]);

  return (
    <div>
      <ul>
        {filteredData.map((item) => (
          <li key={item.id}>{item.name}</li>
        ))}
      </ul>
    </div>
  );
}

export default LargeArrayComponent;

위 코드에서 filteredDatadata 상태가 변경될 때만 다시 계산됩니다. useMemo 훅을 사용하지 않으면, 컴포넌트가 렌더링될 때마다 data 배열을 필터링하는 작업이 반복적으로 수행되어 성능 저하가 발생할 수 있습니다.

리액트 훅: 효율적인 지역 상태 관리를 위한 선택

리액트 훅을 적절히 활용하면 컴포넌트의 상태를 효과적으로 관리하고, 컴포넌트 간의 데이터 흐름을 명확하게 정의할 수 있습니다. 특히, useState 훅과 useEffect 훅은 함수형 컴포넌트에서 지역 상태를 관리하고, 컴포넌트 생명 주기에 따라 특정 작업을 실행하는 데 필수적인 도구입니다.

훅을 사용하면 다음과 같은 장점이 있습니다.

  • 컴포넌트의 가독성 향상: 컴포넌트의 로직을 상태 관리, 생명 주기 관리, 콜백 함수 관리 등으로 분리하여 가독성을 높일 수 있어요.
  • 코드의 재사용성 증가: 훅은 독립적으로 사용할 수 있으므로, 다른 컴포넌트에서도 재사용할 수 있습니다.
  • 컴포넌트 간의 의존성 감소: 컴포넌트 간의 데이터 흐름을 명확하게 정의하여 컴포넌트 간의 의존성을 줄이고, 컴포넌트를 독립적으로 개발 및 테스트할 수 있어요.

지역 상태 관리 팁

  • 컴포넌트의 상태를 최대한 작게 유지하세요.
  • 상태를 업데이트할 때는 setState 함수를 사용하세요.
  • 불필요한 렌더링을 방지하기 위해 useCallbackuseMemo 훅을 활용하세요.
  • 컴포넌트의 생명 주기에 따라 특정 작업을 수행해야 할 경우 useEffect 훅을 사용하세요.

리액트 훅 활용 시 주의 사항

  • 훅은 함수의 최상위 레벨에서만 호출해야 합니다.
  • 훅은 함수형 컴포넌트 내에서만 사용해야 합니다.
  • 훅은 항상 같은 순서로 호출해야 합니다.

훅을 활용한 다양한 상태 관리 패턴

리액트 훅은 단순히 상태를 관리하는 것뿐만 아니라, 더욱 복잡한 상태 관리 패턴을 구현하는 데에도 유용하게 사용될 수 있습니다. 예를 들어, 컨텍스트 API와 함께 훅을 사용하면 전역 상태를 관리하거나, 커스텀 훅을 만들어서 특정 기능을 재사용할 수 있습니다.

컨텍스트 API와 훅을 결합한 전역 상태 관리

컨텍스트 API는 컴포넌트 트리 전체에 데이터를 전달하는 데 사용됩니다. 컨텍스트 API와 훅을 함께 사용하면 전역 상태를 효율적으로 관리할 수 있습니다.

커스텀 훅을 활용한 기능 재사용

커스텀 훅은 여러 컴포넌트에서 재사용 가능한 훅을 만드는 데 사용됩니다. 예를 들어, API 호출, 데이터 로딩, 에러 처리 등의 기능을 커스텀 훅으로 구현하여 여러 컴포넌트에서 재사용할 수 있습니다.

설명
useState 컴포넌트 상태를 선언하고 업데이트
useEffect 컴포넌트 생명 주기에 따라 특정 작업 실행
useCallback 콜백 함수 최적화
useMemo 값 계산 최적화
useRef DOM 요소나 값에 대한 참조 저장
useContext 컨텍스트 API를 통해 전역 상태에 접근

마무리: 리액트 훅으로 더 나은 컴포넌트 만들기

리액트 훅은 함수형 컴포넌트의 기능을 확장하고, 컴포넌트의 상태를 효율적으로 관리하는 데 매우 유용한 도구입니다. useState, useEffect, useCallback, useMemo 등의 훅을 적절하게 활용하면 컴포넌트를 더욱 간결하고 효율적으로 만들 수 있고, 유지보수성과 성능까지 향상시킬 수 있어요.

QnA

Q1. 훅은 왜 사용하는 건가요? A1. 훅은 함수형 컴포넌트에서 상태와 생명주기 기능을 사용할 수 있도록 해줍니다. 클래스 컴포넌트를 사용하지 않고도 함수형 컴포넌트에서 상태를 관리하고, 컴포넌트의 생명 주기에 따라 특정 작업을 실행할 수 있게 해주는 아주 유용한 기능이에요.

Q2. useStateuseEffect는 어떤 차이가 있나요? A2. useState 훅은 컴포넌트의 상태를 관리하는 데 사용됩니다. 반면, useEffect 훅은 컴포넌트의 생명 주기와 관련된 작업을 처리하는 데 사용됩니다. 예를 들어, useState를 사용하여 버튼 클릭 횟수를 저장하고, useEffect를 사용하여 컴포넌트가 마운트될 때 API 호출을 하는 식으로 사용할 수 있어요.

Q3. useCallbackuseMemo는 언제 사용해야 하나요? A3. useCallback은 콜백 함수를 최적화하는 데 사용하고, useMemo는 값을 계산하는 과정을 최적화하는 데 사용합니다. 컴포넌트의 성능을 향상시키고 싶을 때 유용하게 사용할 수 있는 훅들이에요.

리액트,훅,useState,useEffect,useCallback,useMemo,지역상태,상태관리,컴포넌트,함수형컴포넌트,프로그래밍,개발,웹개발,프론트엔드,프론트엔드개발,리액트개발,리액트팁,자바스크립트,JS,개발자,코딩,개발블로그,IT,정보

 

관련 포스트 더 보기

2024.10.10 - [쉽게 배우는 리액트 프로그래밍] - 리액트 프로그래밍: Context API로 전역 상태 관리 마스터하기

 

리액트 프로그래밍: Context API로 전역 상태 관리 마스터하기

리액트 애플리케이션에서 여러 컴포넌트 간에 데이터를 효율적으로 공유하고 싶으신가요? 혹시 컴포넌트 트리를 타고 내려가면서 props를 계속 전달하는 props drilling 때문에 골머리를 앓고 계신

todaypick124.tistory.com

 

반응형