function App() {
const [currentId, setCurrentId] = useState(1);
return (
<div>
<UserProfile userId={currentId} />
<button onClick={() => setCurrentId(2)}>ID를 2로 변경</button>
</div>
);
}
이런 경우 UserProfile에 집중해보자.
버튼 클릭 시 UserProfile이 1 -> 2로 바뀌지만, UserProfile는 언마운트 후 마운트 되지 않는다. 그냥 값만 바뀌고, 재렌더링만 된다. UserProfile 컴포넌트 안에서 useEffect를 사용하면 이를 감지 후 적절한 처리 및 새로 데이터 불러오기 등의 로직을 수행할 수 있음.
따라서 사용자의 입력에 따라 결과를 계산하거나, 변경된 데이터를 API에 저장할 때 사용됨
4. 컴포넌트의 상태가 변경될 때 사용.
state가 변경됨을 감지해서, 그에 맞는 로직을 수행할 때 사용.
useEffect(() => {
// 컴포넌트가 마운트 되거나 업데이트될 때 실행됩니다.
console.log("component updated");
return () => {
// 컴포넌트가 언마운트 되거나 이전의 useEffect가 다시 실행되기 전에 실행됩니다.
console.log("cleanup");
};
}, [someState]); // someState가 변경될 때만 useEffect 내의 코드가 실행됩니다.
import React, { useState, useEffect } from 'react';
function ExampleComponent() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log("useEffect 실행!");
return () => {
console.log("cleanup");
};
}, [count]);
return (
<div>
<button onClick={() => setCount(count + 1)}>증가</button>
</div>
);
}
import React, { useEffect } from 'react';
function User({ user, onRemove, onToggle }) {
useEffect(() => {
console.log('user 값이 설정됨');
console.log(user);
return () => {
console.log('user 가 바뀌기 전..');
console.log(user);
};
}, [user]);
return (
<div>
<b
style={{
cursor: 'pointer',
color: user.active ? 'green' : 'black'
}}
onClick={() => onToggle(user.id)}
>
{user.username}
</b>
<span>({user.email})</span>
<button onClick={() => onRemove(user.id)}>삭제</button>
</div>
);
}
function UserList({ users, onRemove, onToggle }) {
return (
<div>
{users.map(user => (
<User
user={user}
key={user.id}
onRemove={onRemove}
onToggle={onToggle}
/>
))}
</div>
);
}
export default UserList;
참고) 리액트 컴포넌트는 기본적으로 부모 컴포넌트가 리렌더링 되면 자식 컴포넌트 또한 리렌더링 됨.
useEffect 내부에서 참조하는 값이 변경될 가능성이 있는 props거나 state인 경우, 의존성 배열에 넣어야 하는 이유?
const [count, setCount] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
console.log(count); // 항상 초기 값 0을 출력합니다.
}, 1000);
return () => clearInterval(interval); // cleanup
}, []);
const [count, setCount] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
console.log(count);
}, 1000);
return () => clearInterval(interval); // cleanup
}, [count]);