리액트 useState, useEffect 란 무엇일까??
useState의 기본적인 사용법과 목적에 대해 설명
useState는 함수형 컴포넌트에서 상태 관리를 가능하게 하는 React Hook입니다. 클래스 컴포넌트에서 state와 setState를 사용하는 것과 유사한 기능을 제공합니다. useState를 사용하면 상태 값과 그 상태를 업데이트하는 함수가 배열 형태로 반환됩니다. 이를 통해 컴포넌트 내에서 동적인 데이터를 관리할 수 있습니다.
1
const [age, setAge] = useState(20);
이 코드에서 age는 상태 변수이고, setAge는 이 변수를 업데이트하는 함수입니다. setAge 함수에 새로운 값을 전달하면 컴포넌트가 리렌더링되면서 age 상태가 업데이트됩니다.
useState에서 상태 업데이트 시 주의해야 할 점
useState를 사용할 때 주의해야 할 점은 상태 불변성을 유지하는 것입니다. 상태를 업데이트할 때 기존 상태를 직접 수정하지 않고 새로운 상태 값으로 설정해야 합니다. 특히 객체나 배열 같은 복합 자료형을 다룰 때, 기존 상태를 변경하지 않고 새 객체나 배열을 생성해 상태를 업데이트해야 합니다.
1
2
3
4
const [items, setItems] = useState([]);
const addItem = newItem => {
setItems([...items, newItem]);
};
이 예시에서는 기존 items 배열을 직접 수정하지 않고, spread 연산자를 사용해 기존 항목을 복사하고 새 항목을 추가한 새 배열을 생성합니다.
useEffect의 사용법과 작동원리
useEffect는 컴포넌트의 라이프사이클에 따라 사이드 이펙트를 관리할 수 있게 해주는 Hook입니다. 컴포넌트가 렌더링된 후에 실행되며, 의존성 배열(dependency array)에 지정된 변수가 변경될 때마다 이펙트가 재실행됩니다. 의존성 배열을 비우면 컴포넌트 마운트 시 1회 실행되고, 배열을 생략하면 리렌더링될 때마다 실행됩니다.
1
2
3
4
5
6
useEffect(() => {
const timer = setTimeout(() => {
console.log('This will run after 1 second!');
}, 1000);
return () => clearTimeout(timer);
}, []);
이 코드는 컴포넌트가 처음 마운트될 때 1초 후에 메시지를 콘솔에 출력하는 타이머를 설정합니다. useEffect의 반환 함수에서는 타이머를 정리해줍니다. 이는 컴포넌트가 언마운트될 때 실행되어 자원을 정리하는 데 도움을 줍니다.
useEffect에서 의존성 배열의 역할
useEffect의 의존성 배열은 Hook이 특정 값의 변경에 반응하여 실행되어야 함을 리액트에게 알려줍니다. 배열 내의 요소가 변경될 때마다 useEffect 함수가 재실행됩니다. 의존성 배열에 변수를 포함시키지 않으면 useEffect는 컴포넌트가 리렌더링될 때마다 실행되며, 배열이 비어 있으면 컴포넌트 마운트 시와 언마운트 시에만 실행됩니다. 이는 성능 최적화에 중요한 역할을 합니다.
1
2
3
useEffect(() => {
console.log('Component updated:', count);
}, [count]);
이 예시에서는 count라는 상태가 변경될 때마다 콘솔에 메시지를 출력합니다. count 변수가 의존성 배열에 포함되어 있기 때문에, 이 변수가 업데이트될 때마다 useEffect가 재실행되어 최신 상태를 반영하게 됩니다.
useEffect 내에서 API 호출을 처리하는 방법은?
useEffect를 사용하여 컴포넌트가 마운트될 때 원격 데이터를 가져오는 작업을 자주 처리합니다. 이는 컴포넌트가 사용자에게 보여지기 전에 필요한 데이터를 불러올 수 있게 해주며, 의존성 배열을 사용하여 추가 데이터 요청을 효율적으로 관리할 수 있습니다.
예시:
1
2
3
4
5
6
7
8
9
useEffect(() => {
const fetchData = async () => {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
setData(data);
};
fetchData();
}, []); // 의존성 배열을 비워서 컴포넌트 마운트 시에만 실행
useEffect를 사용할 때 발생할 수 있는 문제와 해결 방법
useEffect 내에서 수행되는 작업은 컴포넌트의 라이프사이클과 밀접하게 연결되어 있어, 때때로 메모리 누수와 같은 문제를 야기할 수 있습니다. 특히 외부 데이터 구독이나 타이머 같은 경우에는 컴포넌트가 언마운트되기 전에 이들을 정리해주어야 합니다.
예시:
1
2
3
4
5
6
7
8
9
useEffect(() => {
const timer = setInterval(() => {
console.log('Timer tick');
}, 1000);
return () => {
clearInterval(timer);
};
}, []);
이 예시에서는 컴포넌트가 마운트될 때 타이머를 설정하고, 언마운트될 때 타이머를 정리합니다. 이런 패턴은 메모리 누수를 방지하고, 컴포넌트 외부에서 발생할 수 있는 이펙트들을 안전하게 관리할 수 있게 해줍니다