onChange vs useEffect
작성일 : 2024.12.23
onChange
- 특징:
- 이벤트가 발생할 때마다 직접적으로 실행
- 사용자 입력에 즉각적인 응답 가능
- 동기적으로 실행
- 성능 측면:
// 직접 실행
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const newValue = e.target.value;
setValue(newValue); // 상태 업데이트 1회
validateValue(newValue); // 즉시 검증
};
- 이벤트당 한 번만 실행
- 불필요한 렌더링 없음
- 즉각적인 상태 업데이트 가능
useEffect
- 특징:
- 의존성 배열의 값이 변경될 때마다 실행
- 렌더링 이후에 비동기적으로 실행
- 정리(cleanup) 함수를 통한 부수 효과 처리 가능
- 성능 측면:
useEffect(() => {
validateValue(value); // 의존성 변경마다 실행
return () => {
// cleanup 로직
};
}, [value]); // 값 변경시마다 실행
- 의존성이 변경될 때마다 실행되므로 여러 번 실행될 수 있음
- 추가적인 렌더링 사이클 발생 가능
- 비동기 작업에 적합
사용 시나리오 비교:
- onChange가 더 적합한 경우:
// 즉각적인 입력 처리
const handleChange = (e) => {
const value = e.target.value;
setInput(value);
validateInput(value); // 즉시 검증
};
- 즉각적인 유효성 검사
- 단순한 상태 업데이트
- 동기적 작업
- useEffect가 더 적합한 경우:
useEffect(() => {
const timer = setTimeout(() => {
validateInput(input); // 디바운스된 검증
}, 500);
return () => clearTimeout(timer);
}, [input]);
- API 호출
- 디바운싱/쓰로틀링
- 구독 관리
- 타이머 관리
성능 최적화 예시:
- onChange + useEffect 조합:
const [input, setInput] = useState('');
const [debouncedValue, setDebouncedValue] = useState('');
// 즉각적인 UI 업데이트
const handleChange = (e) => {
setInput(e.target.value);
};
// 디바운스된 검증
useEffect(() => {
const timer = setTimeout(() => {
setDebouncedValue(input);
}, 500);
return () => clearTimeout(timer);
}, [input]);
// API 호출이나 무거운 검증
useEffect(() => {
if (debouncedValue) {
validateWithAPI(debouncedValue);
}
}, [debouncedValue]);
결론적으로:
- 단순 상태 업데이트나 즉각적인 반응이 필요한 경우 → onChange
- 비동기 작업이나 부수 효과 관리가 필요한 경우 → useEffect
- 두 가지를 적절히 조합하여 사용하면 더 나은 성능과 사용자 경험을 제공할 수 있습니다