[React] 클릭시 이미지 변경하기
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;
함수형 업데이트를 사용하는 이유
상태 변경 함수에는 두 가지 방식이 있습니다:
- 값 업데이트:
setIsClicked(true) - 함수형 업데이트:
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는 주로 두 가지 목적으로 사용됩니다:
- 계산 비용이 높은 연산의 결과를 저장하고 재사용하기 위해
- 참조 동일성(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;
- 가독성: 코드가 간결하고 이해하기 쉽습니다.
- 유지보수성: 불필요한 복잡성이 없어 수정이 용이합니다.
- 성능: 단순한 조건 분기는 useMemo 없이도 충분히 빠릅니다.
- 메모리 효율성: useMemo는 이전 값들을 저장하므로 무분별하게 사용하면 메모리 사용 측면에서 비효율적입니다.
정리
- useState: 상태 관리의 기본, 사용자 상호작용 처리에 필수
- useMemo: 복잡한 계산이나 참조 동일성이 중요할 때 사용
- 하트 토글 버튼: useState만으로도 충분하며, 이것이 가장 깨끗한 코드
React 개발에서는 적절한 도구를 적절한 곳에 사용하는 것이 중요합니다. 복잡함을 추가하지 않고 필요한 것에 최적화된
Hook을 사용합니다.
'무비넷' 카테고리의 다른 글
| 웹앱 성능 최적화 (0) | 2025.09.02 |
|---|---|
| 로컬스토리지 연결(워치리스트 컴포넌트) (0) | 2025.05.29 |
| [React]리액트 타입 연결 (0) | 2025.05.23 |
| 프롭스 연결하기 (0) | 2025.05.22 |
| 프로젝트 시작 (0) | 2025.05.08 |