📌 useEffect 훅
리액트 컴포넌트가 렌더링된 후에 비동기적으로 특정 작업을 처리하는 리액트 훅입니다.
컴포넌트가 mount, update, unmount '될 때' 실행된다.
useEffect 훅은 컴포넌트의 렌더링과 동시에 실행되지 않고, 렌더링이 완료된 후에 작업을 수행합니다.
🤔 생명주기(Lifecycle)
생명주기는 컴포넌트가 다음과 같은 단계들을 거치는 것을 의미
- Mounting (마운트) : 컴포넌트가 처음으로 DOM 화면에 추가되는 시점
- Updating (업데이트) : 컴포넌트의 상태(state)나 속성(props)이 변경되어 다시 렌더링 되는 시점
- Unmounting (언마운트) : 컴포넌트가 DOM 화면에서 제거되는 시점
🤔 클래스형 컴포넌트의 생명주기 메서드
클래스형 컴포넌트에서는 다음과 같은 생명주기 메서드를 사용
- componentDidMount() : 컴포넌트가 처음 화면에 나타날 때 실행
- componentDidUpdate() : 컴포넌트가 업데이트된 후 실행
- componentWillUnmount() : 컴포넌트가 화면에서 사라지기 전에 실행
🤔 함수형 컴포넌트와 useEffect
함수형 컴포넌트는 클래스형과 다르게 생명주기 메서드를 가질 수 없기 때문에 생명주기를 처리할 방법이 필요했다.
useEffect 훅이 도입되면서 함수형 컴포넌트에서도 생명주기를 관리할 수 있게 되었다.
- useEffect() : 이 훅을 사용하면 마운트, 업데이트, 언마운트 단계에서 특정 작업 수행가능
📌 useEffect 사용방식
컴포넌트가 화면에 나타날 때, 변할 때, 또는 사라질 때 특정 작업을 수행할 수 있게 도와주는 도구입니다.
- 웹 페이지가 처음 열릴 때 데이터를 가져오기
- 어떤 값이 바뀔 때마다 콘솔에 로그 찍기
- Mounting (마운트) : 컴포넌트가 화면에 처음 나타날 때
- Updating (업데이트) : 컴포넌트가 다시 렌더링될 때
- Unmounting (언마운트) : 컴포넌트가 화면에서 사라질 때
📝 useEffect 기본문법
useEffect는 컴포넌트가 렌더링된 후 비동기적으로 사이드 이펙트를 처리합니다.
- 사이드 이펙트(Side Effects)
- 화면에 직접적으로 그려지지 않는, 컴포넌트가 렌더링된 후에
백그라운드에서 실행되는 작업을 의미합니다.
(예: 서버에서 데이터 가져오기, 타이머 설정 등)
- 화면에 직접적으로 그려지지 않는, 컴포넌트가 렌더링된 후에
- Cleanup 로직
- 컴포넌트가 화면에서 사라지거나 업데이트되기 전에,
사이드 이펙트를 정리하는 작업을 수행합니다.
(예: 타이머 멈추기, 이벤트 리스너 제거 등)
- 컴포넌트가 화면에서 사라지거나 업데이트되기 전에,
- 의존성 배열
- useEffect가 언제 실행될지 결정하는 배열입니다.
배열에 포함된 값이 바뀔 때마다 useEffect가 다시 실행됩니다.
배열이 비어 있으면 컴포넌트가 처음 렌더링될 때만 실행됩니다.
- useEffect가 언제 실행될지 결정하는 배열입니다.
import React, { useEffect } from 'react';
useEffect(() => {
// ▶ Side effects 수행 (예: 데이터 가져오기, 타이머 설정 등)
return () => {
// ▶ cleanup 로직 (예: 타이머 정리, 이벤트 리스너 제거 등)
};
}, [/* 의존성 배열 */]); // ▶ 의존성 배열에 있는 값이 바뀔 때 useEffect가 실행
✅ Mounting(마운트) - 컴포넌트가 화면에 처음 나타날 때
컴포넌트가 처음 화면에 나타날 때만 실행하려면 의존성 배열(deps)에 빈 배열 []을 넣습니다.
useEffect(() => {
console.log('컴포넌트가 마운트될 때만 실행됩니다.');
}, []); // 빈 배열 : 처음 한 번만 실행
➕ 렌더링될 때마다 실행 (매번 화면이 다시 그려질 때 실행)
의존성 배열을 생략하면, 컴포넌트가 렌더링될 때마다 실행됩니다.
useEffect(() => {
console.log('컴포넌트가 렌더링될 때마다 실행됩니다.');
}); // 빈 배열 생략 : 매번 실행
✅ Updating(업데이트) - 특정 값이 변경될 때
특정 값이 바뀔 때 실행되도록 하고 싶다면, 의존성 배열(deps)에 해당 값을 넣습니다.
useEffect(() => {
console.log(name);
console.log('name이 변경될 때 실행됩니다.');
}, [name]); // name이 바뀔 때마다 실행
➕ 마운트와 업데이트 시 실행 (처음과 바뀔 때만 실행)
처음 화면에 나타날 때와 값이 바뀔 때만 실행하고 싶다면
useRef를 사용해서 첫 번째 실행을 건너뛸 수 있어요.
import { useEffect, useRef } from 'react';
const mounted = useRef(false);
useEffect(() => {
if (!mounted.current) {
mounted.current = true; // 첫 렌더링은 건너뜀
} else {
console.log(name);
console.log("업데이트될 때마다 실행");
}
}, [name]);
✅ Unmounting (언마운트) - 컴포넌트가 사라질 때
컴포넌트가 화면에서 사라지거나 업데이트되기 직전에 실행
return 안에 정의한 함수가 cleanup 함수로, 컴포넌트가 사라질 때나 업데이트 직전에 실행됩니다.
useEffect(() => {
console.log('effect 실행');
return () => {
console.log('컴포넌트가 사라질 때 정리 작업 실행');
};
}, []);
사용예시
🕒 화면에 컴포넌트가 나타날 때 타이머를 시작하고, 사라질 때 타이머를 멈춘다.
이렇게 return에 clearInterval을 통해서 타이머를 멈추는 코드를 넣어주게 되면!
useEffect가 처음 렌더링 될때는 타이머가 시작되고 화면에서 사라지게 되면 return을 통해서 타이머는 멈추게 된다.
return을 통해서 종료시키지 않는다면 현재코드에서는 console에 "타이머"는 1초간격으로 계속 나오게 된다.
복잡한 로직이나 긴 코드 함수가 종료되지않고 계속 실행될 수 있다는걸 잊지말자.
const Timer = () => {
useEffect(() => {
const timer = setInterval(() => {
console.log("타이머 작동 중");
}, 1000); // 1초마다 '타이머 작동 중'을 출력
return () => {
clearInterval(timer); // 컴포넌트가 사라질 때 타이머를 멈춘다
};
}, []); // 처음 나타날 때 한 번 실행
};
✏️ useEffect 사용해보기
컴포넌트의 생명주기 동안 비동기 작업을 처리하고, 상태를 업데이트하며,
사용자에게 적절한 피드백을 제공하는 데 유용합니다.
- 데이터 가져오기
useEffect 안에서 fetch를 사용하여 외부 API에서 데이터를 가져옵니다.
이는 컴포넌트가 처음 렌더링될 때 한 번만 실행됩니다. - 상태 관리
useState 훅을 사용하여
데이터를 상태로 저장하고, 데이터가 로드되면 컴포넌트를 다시 렌더링하여
로드된 데이터를 화면에 표시합니다. - 의존성 배열
빈 배열 []을 useEffect의 두 번째 인자로 전달하여,
컴포넌트가 처음 렌더링될 때만 useEffect가 실행되도록 합니다.
이는 API 호출을 한 번만 수행하게 합니다. - 로딩 상태 표시
데이터가 아직 로드되지 않았을 때는 "Loading..." 텍스트를 보여주고,
데이터가 로드되면 해당 데이터를 화면에 표시합니다.
import React, { useState, useEffect } from 'react';
import { View, Text } from 'react-native';
const DataFetchingComponent = () => {
// ▶ 상태 변수 선언
const [data, setData] = useState(null);
useEffect(() => {
// ▶ API에서 데이터를 가져온다
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => setData(data)) // 데이터를 상태로 저장합니다.
.catch(error => console.error('Error fetching data:', error)); // 오류 처리
}, []); // 빈 배열을 사용하여 컴포넌트가 처음 렌더링될 때만 effect를 실행합니다.
return (
<View>
{/* 데이터가 로드되었는지 여부에 따라 다른 내용을 렌더링합니다. */}
{data ? <Text>{data}</Text> : <Text>Loading...</Text>}
</View>
);
};
'📌 Front End > └ React' 카테고리의 다른 글
[React] 리액트 훅 - useRef(리렌더링 방지 DOM요소 접근) (1) | 2024.08.30 |
---|---|
[React] 리액트 훅 - useMemo, useCallback(메모이제이션 값, 함수 반환) (0) | 2024.08.30 |
[React] 리액트 훅 - useContext(전역 상태값 공유) (0) | 2024.08.29 |
[React] 리액트 훅 - useReducer(관리 코드 컴포넌트 외부 분리) (0) | 2024.08.28 |
[React] 리액트 이벤트 처리 - 핸들러, 컴포넌트 상태(useState), 단방향 바인딩 (0) | 2024.08.26 |