본문 바로가기

Frontend

[React] useEffect 사용해보기

 

 

[React] useState 사용해보기

멘토님께서 React에서 제공하는 useHook 중 몇 개를 써보았는지 물어보시며한번씩 다 써보는걸 추천하셨다. 그래서 하나씩 직접 써보고 정리해보기로 했다.🙂 React에서 가장 자주 사용되는 Hook인 us

min-i0212.tistory.com

이전 편에 이어 이번엔 useEffect를 사용해보자

 

React에서 컴포넌트의 렌더링 외 작업이 필요한 순간이 있다.

 

예를 들자면

- API 요청

- 이벤트 리스너 등록

- 타이머 설정

- 외부 상태 동기화

등등..

 

이런 작업들을 사이드 이펙트라고 하며, 이를 처리하기 위해 useEffect라는 Hook을 제공한다.

 

useEffect란?

컴포넌트가 마운트(렌더링)된 이후 실행되는 코드 블록을 정의할 수 있게 해주는 Hook이다.

useEffect(() => {
  // 실행할 작업
}, [의존성]);

- 첫번째 인자: 실행할 함수

- 두번째 인자: 의존성 배열

  - 빈 배열일 경우, 마운트 시 1회만 실행

  - 특정 값이 변경될 때마다 실행

  - 생략하면 모든 렌더링마다 실행

 

실습해보기

창 크기 감지하기

import { useEffect, useState } from "react";

const WindowSize = () => {
	const [width, setWidth] = useState(window.innerWidth);

	useEffect(() => {
		const handleResize = () => setWidth(window.innerWidth);

		window.addEventListener("resize", handleResize);
		return () => {
			window.removeEventListener("resize", handleResize);
			console.log("clear eventlistener");
		};
	}, []);

	return (
		<div>
			<h2>윈도우 크기 감지</h2>
			<p>현재 창 너비: {width}px</p>
		</div>
	);
};

export default WindowSize;

컴포넌트가 마운트되면 창 크기를 감지하고, 언마운트시 이벤트 리스너를 해제하여 메모리 누수를 방지한다.

키보드 입력

import { useEffect, useState } from "react";

const KeyInputTracker = () => {
	const [input, setInput] = useState("");
	const [length, setLength] = useState(0);

	useEffect(() => {
		setLength(input.length);
	}, [input]); // input 값이 바뀔 때만 실행

	return (
		<div>
			<h2>입력 길이 감지</h2>
			<input
				value={input}
				onChange={(e) => setInput(e.target.value)}
				placeholder="입력하기"
			/>
			<p>글자 수: {length}</p>
		</div>
	);
};

export default KeyInputTracker;

input에 텍스트가 입력될 때마다 길이를 감지한다.

input상태가 바뀔 때만 실행하도록 설정했다.

 

실행 결과

useEffect 클린업 함수

useEffect에서 반환하는 함수로 컴포넌트가 언마운트 되거나 의존성 값이 바뀌기 직전에 실행되는 정리코드이다.

useEffect(() => {
  // effect 실행 시 수행됨
  console.log("Effect 실행");

  return () => {
    // 컴포넌트 언마운트 시 또는 의존성 변경 직전에 실행됨
    console.log("클린업 함수 실행");
  };
}, [의존성]);

클린업 함수가 필요한 이유

- 이벤트 리스너 등록 후 제거하지 않으면 중복 실행이 되거나 메모리 누수가 일어날 수 있음

- 타이머의 경우 컴포넌트가 사라져도 계속 동작하게 됨

- WebSocket의 경우 연결이 유지되기에 리소스가 낭비될 수 있음

 

비동기 함수는 어떻게 사용해야 할까?

useEffect는 클린업 함수나 undefined를 반환해야하는데 async함수는 항상 Promise를 반환한다.

따라서 async함수를 호출하려면 내부에서 정의해서 호출해야 한다

useEffect(() => {
  const fetchData = async () => {
    const res = await fetch("/api/~");
    const json = await res.json();
    setData(json);
  };

  fetchData();
}, []);

정리

- useEffect는 렌더링 후 실행되는 사이드 이펙트 처리 도구이다.

- 마운트/언마운트 시점, 특정 값이 바뀔 때만 실행되도록 제어할 수 있다.

- 클린업 함수의 중요성을 잊지 말자!

 

 

추가적으로 React 공식 문서의 트러블 슈팅을 읽어보면 개발시 버그 해결에 많은 도움이 된다.

예를 들어 마운트가 두번 되는 이슈라거나...

 

 

 

useEffect – React

The library for web and native user interfaces

react.dev