React에서 버튼 클릭시 색상 변경하기

React로 하트(좋아요) 버튼을 구현할 때 어떤 훅을 사용할지 고민하였습니다.

아래는 useState와 useMemo의 차이점을 비교하고, 하트 버튼에서 활용하는 과정입니다.


useState

useState는 React의 내장 Hook으로, 함수형 컴포넌트에서 상태를 관리할 수 있게 해주는 기능입니다. useState를 사용하면 시간이 지남에 따라 변경될 수 있는 값을 저장하고 관리할 수 있습니다.

useState 기본 사용법

const [상태 변수, 상태 변경 함수] = useState(초기값);

useState 함수에 초기 상태 값을 매개변수로 호출하면 배열이 반환됩니다. 이 배열에는 현재 값을 나타내는 상태 변수와 상태 값을 변경하는데 사용하는 함수가 들어가 있습니다.

useState로 구현하기

가장 기본적이고 직관적인 방법은 useState를 사용하는 것입니다.

import React, { useState } from "react";

const Ranking = () => {
  const [isClicked, setIsClicked] = useState(false);

  const handleClick = () => setIsClicked((prev) => !prev);

  // 상태에 따라 하트 이미지 경로를 결정
  const heartImg = isClicked
    ? "src/imgs/pinkheart.png"
    : "src/imgs/greyheart.png";

  return (
    <img
      src={heartImg}
      alt="heart"
      onClick={handleClick}
      style={{ cursor: "pointer" }}
    />
  );
};

export default Ranking;

함수형 업데이트를 사용하는 이유

상태 변경 함수에는 두 가지 방식이 있습니다:

  1. 값 업데이트: setIsClicked(true)
  2. 함수형 업데이트: setIsClicked(prev => !prev)

함수형 업데이트 방식을 권장하는 이유는 React의 상태 변경 함수가 비동기적으로 동작하기 때문입니다. setCount 함수를 호출하는 시간과 상태가 실제로 업데이트되는 사이에 지연이 있을 수 있어, 함수형 업데이트를 사용하면 버그를 방지하고 성능을 개선할 수 있습니다.


useMemo

useMemo는 재렌더링 사이에 계산 결과를 캐싱할 수 있게 해주는 React Hook입니다. 주로 비용이 많이 드는 연산을 수행할 때 사용되며, 메모이제이션(memoization) 기술을 통해 중복 계산을 피하고 성능을 최적화합니다.

useMemo 기본 사용법

const cachedValue = useMemo(calculateValue, dependencies);

useMemo의 첫 번째 인자는 실행할 함수이고, 두 번째 인자는 의존성 배열입니다. 이 배열의 값이 변경될 때만 함수가 다시 실행됩니다.

useMemo로 구현하기

useMemo를 사용해서 하트 이미지 경로를 관리할 수도 있습니다:

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

const Ranking = () => {
  const [isClicked, setIsClicked] = useState(false);

  // useMemo로 이미지 경로를 관리
  const heartImg = useMemo(
    () => (isClicked ? "src/imgs/pinkheart.png" : "src/imgs/greyheart.png"),
    [isClicked]
  );

  const handleClick = () => {
    setIsClicked((prev) => !prev);
  };

  return (
    <img
      src={heartImg}
      alt="heart"
      onClick={handleClick}
      style={{ cursor: "pointer" }}
    />
  );
};

export default Ranking;

useState를 사용해야 하는 경우

  • 사용자 상호작용에 따라 값이 변해야 할 때
  • 컴포넌트 내부에서 상태를 직접 관리할 때
  • 간단한 상태 관리가 필요할 때

useState는 상태 관리의 기본이며, 클릭과 같은 사용자 상호작용을 처리하는 데 필수적입니다.

useMemo를 사용해야 하는 경우

useMemo는 주로 두 가지 목적으로 사용됩니다:

  1. 계산 비용이 높은 연산의 결과를 저장하고 재사용하기 위해
  2. 참조 동일성(Reference Equality)을 유지하기 위해

하지만 하트 버튼의 경우, 단순히 isClicked 값에 따라 이미지 경로가 바뀌는 것이므로 useMemo를 사용해도 성능상 큰 차이는 없습니다.


적용 사례

하트 버튼 구현에서 생각한 최선의 코드는 useState만 사용하는 것입니다.

import React, { useState } from "react";
import pinkHeart from "../../imgs/pinkheart.png";
import greyHeart from "../../imgs/greyheart.png";

const Ranking = () => {
  const [isClicked, setIsClicked] = useState(false);
  const handleClick = () => setIsClicked((prev) => !prev);

  return (
    <img
      src={isClicked?pinkHeart: greyHeart}
      alt="heart"
      onClick={handleClick}
      style={{ cursor: "pointer" }}
    />
  );
};

export default Ranking;
  1. 가독성: 코드가 간결하고 이해하기 쉽습니다.
  2. 유지보수성: 불필요한 복잡성이 없어 수정이 용이합니다.
  3. 성능: 단순한 조건 분기는 useMemo 없이도 충분히 빠릅니다.
  4. 메모리 효율성: useMemo는 이전 값들을 저장하므로 무분별하게 사용하면 메모리 사용 측면에서 비효율적입니다.

정리

  • useState: 상태 관리의 기본, 사용자 상호작용 처리에 필수
  • useMemo: 복잡한 계산이나 참조 동일성이 중요할 때 사용
  • 하트 토글 버튼: useState만으로도 충분하며, 이것이 가장 깨끗한 코드

React 개발에서는 적절한 도구를 적절한 곳에 사용하는 것이 중요합니다. 복잡함을 추가하지 않고 필요한 것에 최적화된

Hook을 사용합니다.

728x90

'무비넷' 카테고리의 다른 글

웹앱 성능 최적화  (0) 2025.09.02
로컬스토리지 연결(워치리스트 컴포넌트)  (0) 2025.05.29
[React]리액트 타입 연결  (0) 2025.05.23
프롭스 연결하기  (0) 2025.05.22
프로젝트 시작  (0) 2025.05.08