반응형
회사에서 잘못된 useEffect 사용으로 인해 화면에 무한루프가 걸리는 문제가 발생했다.
내가 원인도 파악을 못해서, 과장님이 의심되는 부분 확인해주셨다. 문제는 새로고침 후, 팝업 렌더링에서 useEffect 를 사용하는게 문제였다. useEffect 를 사용하며 새로고침이 발생해, 로그인 인증을 재실행하고, 인증 재실행 후 팝업 렌더링이 재실행되는 무한루프에 빠진 것이다.
어렴풋이 사용하고 있던 useState 와 useEffect 를 정리하고자 한다.
useState
- useState 는 컴포넌트의 상태 (데이터) 를 관리하기 위해 사용한다.
- useState는 컴포넌트가 기억해야 할 값 (상태) 를 만들고 관리할 수 있게 해주는 Hook이다.
- 컴포넌트 내에서 변경될 수 있는 데이터를 관리한다.
- useState 를 호출하면 [현재 상태 값, 상태를 변경하는 함수] 배열이 반환된다. 상태 변경 함수가 호출되어 상태가 바뀌면, React 가 해당 컴포넌트를 다시 렌더링 한다.
- useState 에 담긴 값들은 리렌더링 되어도 값을 기억해줌. 값이 바뀌면 화면을 새로고침해줌.
- 기억이 필요한 모든곳 (사용자 입력, 로딩 여부, 서버 데이터 등)
예) 사용자의 id 와 pw 값을 기억하기 위해 useState 사용
import { useState } from 'react';
function LoginForm() {
// 1. 'id'와 'pw' 값을 "기억"하기 위해 useState를 사용
const [id, setId] = useState('');
const [pw, setPw] = useState('');
return (
<div>
<input
value={id}
onChange={(e) => setId(e.target.value)} // 2. 키보드를 칠 때마다 'id' 기억 상자를 업데이트
/>
<input
value={pw}
onChange={(e) => setPw(e.target.value)} // 3. 키보드를 칠 때마다 'pw' 기억 상자를 업데이트
/>
<p>입력한 ID: {id}</p> {/* 4. 기억한 값을 화면에 보여줌 */}
</div>
);
}
useEffect
- useEffect 는 컴포넌트의 사이드 이펙트 (행동) 을 처리하기 위해 사용한다.
- 컴포넌트가 렌더링된 후에 특정 작업을 수행하고 싶을 때 사용하는 Hook이다.
- 렌더링과 직접적인 관련이 없는 부수적인 작업들을 처리한다.
- window.onload 와 유사하지만 더 기능이 많다. window.onload 처럼 처음 한번, 특정 값이 바뀔 때마다, 컴포넌트가 사라질 때 실행이 될 수 있다.
- 행동이 필요한 곳 (데이터 요청, 타이머, DOM 조작 등)
예) useState와 useEffect 를 함께 써야 할 경우
페이지가 처음 뜰 때 서버에서 사용자 목록 가져오기.
- 서버에서 받아온 "사용자 목록"을 기억할 useState
- 로딩 중인지 아닌지를 기억할 useState
- 화면이 처음 뜰 때 한 번 서버에 사용자 목록 요청을 보내는 useEffect
import { useState, useEffect } from 'react';
function UserList() {
// 1. 기억 useState 준비
const [users, setUsers] = useState([]);
const [isLoading, setIsLoading] = useState(true);
// 2. 행동 지시서 useEffect
useEffect (() => {
// 3. 서버에서 데이터 가져오는 행동
fetch('/api/users')
.then (res => res.json())
.then (data => {
setUsers(data); // 4. 받아온 데이터 기억 useState 에 저장
setIsLoading(false); // 5. 로딩 끝났음을 저장
});
}, []); // 6. 빈 배열 : 이 행동은 처음 한번만 실행.
// 7. 기억 값을 바탕으로 화면 로드.
if (isLoading) {
return <div> 로딩 중 </div>;
}
return (
<ul>
{users.map(item => <li key={item.id}>{item.name}</li>)}
</ul>
);
}

React 에서는 useEffect 로 인해 무한 로딩, 무한루프가 발생되는 경우가 많다.
유의해서 사용하자 !
반응형