🕐 커밋 시간: 2025. 11. 20. 06:13:41 📊 변경 통계: • 총 파일: 3개 • 추가: +71줄 • 삭제: -74줄 📝 수정된 파일: ~ com.twin.app.shoptime/src/hooks/usePrevious.js ~ com.twin.app.shoptime/src/hooks/usePrevious.test.js ~ com.twin.app.shoptime/src/hooks/usePreviousExample.jsx 🔧 주요 변경 내용: • 핵심 비즈니스 로직 개선 • 테스트 커버리지 및 안정성 향상 • 소규모 기능 개선 • 코드 정리 및 최적화 Performance: 코드 최적화로 성능 개선 기대
246 lines
7.4 KiB
JavaScript
246 lines
7.4 KiB
JavaScript
import { useState } from 'react';
|
|
import usePrevious from './usePrevious';
|
|
|
|
/**
|
|
* usePrevious 훅의 다양한 사용 예시를 보여주는 컴포넌트
|
|
*/
|
|
|
|
// 예시 1: 단일 값 추적 - 카운터
|
|
export function CounterExample() {
|
|
const [count, setCount] = useState(0);
|
|
const prevCountRef = usePrevious(count);
|
|
|
|
return (
|
|
<div style={{ padding: '20px', border: '1px solid #ccc', marginBottom: '20px' }}>
|
|
<h3>예시 1: 단일 값 추적 (카운터)</h3>
|
|
<p>현재값: {count}</p>
|
|
<p>이전값: {prevCountRef.current !== undefined ? prevCountRef.current : '초기값'}</p>
|
|
<button onClick={() => setCount(count + 1)}>증가</button>
|
|
<button onClick={() => setCount(count - 1)}>감소</button>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// 예시 2: 다중 값 추적 (객체) - 사용자 정보
|
|
export function UserFormExample() {
|
|
const [name, setName] = useState('');
|
|
const [age, setAge] = useState('');
|
|
const [email, setEmail] = useState('');
|
|
|
|
const prevRef = usePrevious({ name, age, email });
|
|
const prev = prevRef.current;
|
|
|
|
const hasNameChanged = prev?.name !== name;
|
|
const hasAgeChanged = prev?.age !== age;
|
|
const hasEmailChanged = prev?.email !== email;
|
|
|
|
return (
|
|
<div style={{ padding: '20px', border: '1px solid #ccc', marginBottom: '20px' }}>
|
|
<h3>예시 2: 다중 값 추적 (객체) - 사용자 정보</h3>
|
|
|
|
<div style={{ marginBottom: '10px' }}>
|
|
<label>
|
|
이름:
|
|
<input
|
|
type="text"
|
|
value={name}
|
|
onChange={(e) => setName(e.target.value)}
|
|
style={{ marginLeft: '10px' }}
|
|
/>
|
|
{hasNameChanged && <span style={{ color: 'red', marginLeft: '10px' }}>변경됨</span>}
|
|
</label>
|
|
</div>
|
|
|
|
<div style={{ marginBottom: '10px' }}>
|
|
<label>
|
|
나이:
|
|
<input
|
|
type="text"
|
|
value={age}
|
|
onChange={(e) => setAge(e.target.value)}
|
|
style={{ marginLeft: '10px' }}
|
|
/>
|
|
{hasAgeChanged && <span style={{ color: 'red', marginLeft: '10px' }}>변경됨</span>}
|
|
</label>
|
|
</div>
|
|
|
|
<div style={{ marginBottom: '10px' }}>
|
|
<label>
|
|
이메일:
|
|
<input
|
|
type="text"
|
|
value={email}
|
|
onChange={(e) => setEmail(e.target.value)}
|
|
style={{ marginLeft: '10px' }}
|
|
/>
|
|
{hasEmailChanged && <span style={{ color: 'red', marginLeft: '10px' }}>변경됨</span>}
|
|
</label>
|
|
</div>
|
|
|
|
<div style={{ marginTop: '15px', padding: '10px', backgroundColor: '#f5f5f5' }}>
|
|
<h4>이전 값</h4>
|
|
<p>이름: {prev?.name || '(없음)'}</p>
|
|
<p>나이: {prev?.age || '(없음)'}</p>
|
|
<p>이메일: {prev?.email || '(없음)'}</p>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// 예시 3: 배열 값 추적 - 다중 숫자
|
|
export function ArrayValuesExample() {
|
|
const [a, setA] = useState(0);
|
|
const [b, setB] = useState(0);
|
|
const [c, setC] = useState(0);
|
|
|
|
const prevRef = usePrevious([a, b, c]);
|
|
const [prevA, prevB, prevC] = prevRef.current || [];
|
|
|
|
return (
|
|
<div style={{ padding: '20px', border: '1px solid #ccc', marginBottom: '20px' }}>
|
|
<h3>예시 3: 배열 값 추적 - 다중 숫자</h3>
|
|
|
|
<div style={{ marginBottom: '15px' }}>
|
|
<div>
|
|
<label>
|
|
A:
|
|
<input
|
|
type="number"
|
|
value={a}
|
|
onChange={(e) => setA(Number(e.target.value))}
|
|
style={{ marginLeft: '10px' }}
|
|
/>
|
|
</label>
|
|
<span style={{ marginLeft: '20px' }}>이전: {prevA !== undefined ? prevA : '초기값'}</span>
|
|
</div>
|
|
|
|
<div style={{ marginTop: '10px' }}>
|
|
<label>
|
|
B:
|
|
<input
|
|
type="number"
|
|
value={b}
|
|
onChange={(e) => setB(Number(e.target.value))}
|
|
style={{ marginLeft: '10px' }}
|
|
/>
|
|
</label>
|
|
<span style={{ marginLeft: '20px' }}>이전: {prevB !== undefined ? prevB : '초기값'}</span>
|
|
</div>
|
|
|
|
<div style={{ marginTop: '10px' }}>
|
|
<label>
|
|
C:
|
|
<input
|
|
type="number"
|
|
value={c}
|
|
onChange={(e) => setC(Number(e.target.value))}
|
|
style={{ marginLeft: '10px' }}
|
|
/>
|
|
</label>
|
|
<span style={{ marginLeft: '20px' }}>이전: {prevC !== undefined ? prevC : '초기값'}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// 예시 4: 변동 감지 - 데이터 수정 여부 추적
|
|
export function ChangeDetectionExample() {
|
|
const [data, setData] = useState({
|
|
title: 'React Hook Guide',
|
|
description: 'usePrevious 훅 사용법',
|
|
views: 1000,
|
|
});
|
|
|
|
const prevDataRef = usePrevious(data);
|
|
const prevData = prevDataRef.current;
|
|
|
|
const changes = {
|
|
titleChanged: prevData?.title !== data.title,
|
|
descriptionChanged: prevData?.description !== data.description,
|
|
viewsChanged: prevData?.views !== data.views,
|
|
};
|
|
|
|
const hasAnyChanges = Object.values(changes).some((v) => v);
|
|
|
|
const handleUpdate = (field, value) => {
|
|
setData((prev) => ({ ...prev, [field]: value }));
|
|
};
|
|
|
|
return (
|
|
<div style={{ padding: '20px', border: '1px solid #ccc', marginBottom: '20px' }}>
|
|
<h3>예시 4: 변동 감지 - 데이터 수정 여부 추적</h3>
|
|
|
|
<div style={{ marginBottom: '15px' }}>
|
|
<label>
|
|
제목:
|
|
<input
|
|
type="text"
|
|
value={data.title}
|
|
onChange={(e) => handleUpdate('title', e.target.value)}
|
|
style={{ marginLeft: '10px', width: '200px' }}
|
|
/>
|
|
{changes.titleChanged && (
|
|
<span style={{ color: 'orange', marginLeft: '10px' }}>수정됨</span>
|
|
)}
|
|
</label>
|
|
</div>
|
|
|
|
<div style={{ marginBottom: '15px' }}>
|
|
<label>
|
|
설명:
|
|
<input
|
|
type="text"
|
|
value={data.description}
|
|
onChange={(e) => handleUpdate('description', e.target.value)}
|
|
style={{ marginLeft: '10px', width: '200px' }}
|
|
/>
|
|
{changes.descriptionChanged && (
|
|
<span style={{ color: 'orange', marginLeft: '10px' }}>수정됨</span>
|
|
)}
|
|
</label>
|
|
</div>
|
|
|
|
<div style={{ marginBottom: '15px' }}>
|
|
<label>
|
|
조회수:
|
|
<input
|
|
type="number"
|
|
value={data.views}
|
|
onChange={(e) => handleUpdate('views', Number(e.target.value))}
|
|
style={{ marginLeft: '10px' }}
|
|
/>
|
|
{changes.viewsChanged && (
|
|
<span style={{ color: 'orange', marginLeft: '10px' }}>수정됨</span>
|
|
)}
|
|
</label>
|
|
</div>
|
|
|
|
<div style={{ padding: '10px', backgroundColor: hasAnyChanges ? '#fff3cd' : '#e8f5e9' }}>
|
|
<p style={{ margin: '0' }}>
|
|
<strong>
|
|
상태: {hasAnyChanges ? '데이터가 변경되었습니다' : '모든 데이터가 저장되었습니다'}
|
|
</strong>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// 전체 예시 조합
|
|
export function UsePreviousExamples() {
|
|
return (
|
|
<div style={{ padding: '20px', fontFamily: 'Arial, sans-serif' }}>
|
|
<h1>usePrevious 훅 사용 예시</h1>
|
|
<p>이전 값을 추적하는 다양한 방법을 보여주는 예시들입니다.</p>
|
|
|
|
<CounterExample />
|
|
<UserFormExample />
|
|
<ArrayValuesExample />
|
|
<ChangeDetectionExample />
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default UsePreviousExamples;
|