728x90
1. Escape Hatches: React의 예외 처리 방법
React는 선언형 UI 라이브러리이지만, 때때로 imperative(명령형) 접근이 필요할 때가 있습니다. 이런 경우를 위해 React는 몇 가지 "Escape Hatches(탈출구)"를 제공합니다.
1.1 useRef
- 상태(state)처럼 값이 유지되지만 렌더링을 트리거하지 않음.
- 주로 DOM 요소에 직접 접근하거나 값이 변하지만 렌더링이 필요 없는 경우 사용.
1.2 forwardRef
- 부모 컴포넌트에서 자식 컴포넌트의 DOM 요소에 직접 접근해야 할 때 사용.
- ref를 props로 넘겨받아 특정 요소를 참조 가능.
1.3 useImperativeHandle
- forwardRef와 함께 사용하여, 부모가 특정 기능을 자식 컴포넌트에 제공할 수 있도록 함.
- 예: 특정 버튼을 외부에서 클릭할 수 있도록 하는 기능 구현.
2. Refs: 값 참조 및 직접 DOM 조작
Refs는 React에서 DOM 요소나 특정 값을 직접 참조할 때 사용합니다.
2.1 useRef로 값 유지하기
- useState와 달리 값이 변경되어도 컴포넌트가 리렌더링되지 않음.
- 예: 이전 값을 저장하거나, 타이머 ID 등을 저장할 때 유용.
import { useRef } from 'react';
function TimerComponent() {
const timerId = useRef(null);
const startTimer = () => {
timerId.current = setTimeout(() => {
console.log('타이머 끝!');
}, 3000);
};
const stopTimer = () => {
clearTimeout(timerId.current);
};
return (
<div>
<button onClick={startTimer}>타이머 시작</button>
<button onClick={stopTimer}>타이머 중지</button>
</div>
);
}
2.2 useRef를 활용한 DOM 요소 조작
- document.querySelector를 대체하는 방식.
import { useRef } from 'react';
function FocusInput() {
const inputRef = useRef(null);
const handleFocus = () => {
inputRef.current.focus();
};
return (
<div>
<input ref={inputRef} type="text" placeholder="여기에 입력" />
<button onClick={handleFocus}>포커스 주기</button>
</div>
);
}
3. Effects: 사이드 이펙트 관리
useEffect는 React에서 네트워크 요청, 구독 설정, DOM 변경 등을 처리할 때 사용됩니다.
3.1 기본적인 useEffect
- 렌더링 이후 특정 작업을 실행하고, 의존성 배열을 통해 실행 조건을 관리.
import { useEffect, useState } from 'react';
function ExampleComponent() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log(`현재 카운트: ${count}`);
}, [count]); // count가 변경될 때마다 실행
return <button onClick={() => setCount(count + 1)}>증가</button>;
}
3.2 불필요한 useEffect 방지하기
- 많은 경우 useEffect 없이도 구현 가능.
- 예: useState의 콜백을 활용하여 상태 변경을 처리.
const [count, setCount] = useState(0);
const increment = () => {
setCount(prevCount => prevCount + 1);
};
3.3 useEffect 정리하기 (cleanup 함수)
- 구독을 해제하거나 타이머를 제거해야 하는 경우 사용.
useEffect(() => {
const interval = setInterval(() => {
console.log('타이머 실행 중');
}, 1000);
return () => clearInterval(interval); // 언마운트 시 타이머 정리
}, []);
4. Lifecycle of Reactive Effects: useEffect의 실행 흐름
4.1 useEffect 실행 과정
- 초기 렌더링 후 실행됨.
- 의존성 배열이 변경될 때 실행됨.
- 컴포넌트가 언마운트될 때 cleanup 함수 실행됨.
4.2 useEffect를 활용한 비동기 데이터 요청
useEffect(() => {
let isMounted = true;
fetch('/api/data')
.then(res => res.json())
.then(data => {
if (isMounted) {
console.log(data);
}
});
return () => {
isMounted = false;
};
}, []);
5. Separating Events from Effects: 이벤트 로직과 Effect 분리하기
- useEffect를 이벤트 핸들러 내부에서 호출하지 않고, 상태 업데이트만 담당하도록 구현.
function Component() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log(`Count 변경됨: ${count}`);
}, [count]);
return <button onClick={() => setCount(count + 1)}>증가</button>;
}
6. Removing Effect Dependencies: 불필요한 의존성 줄이기
- useCallback과 useMemo를 활용하여 불필요한 렌더링 방지.
const memoizedFunction = useCallback(() => {
console.log('값 변경됨');
}, []); // 의존성 배열을 비워서 매번 생성되지 않도록 함
결론
위에서 설명한 개념들은 React에서 좀 더 최적화된 방식으로 상태와 DOM을 다룰 수 있도록 도와줍니다(적절히 사용할시!). useEffect의 적절한 사용, useRef를 활용한 DOM 조작, 그리고 불필요한 Effect 의존성 제거 등을 익히면 보다 깔끔한 코드 작성이 가능합니다.
그럼 오늘도 즐코 빡코 !
728x90
LIST
'React' 카테고리의 다른 글
React 상태 관리 정리 (1) | 2025.03.09 |
---|---|
React 상태 관리와 입력 반응 정리 (0) | 2025.03.06 |
React에서 객체 및 배열 상태 업데이트하기 (1) | 2025.03.02 |
React의 상태(State)란 무엇인가? (2) | 2025.03.02 |
React의 렌더링과 커밋 과정: 개념부터 이해하기 (4) | 2025.02.23 |