React 배움의 연속 #9
#9 어렵다! 리액트 <- 너
useEffect의 사용방법
이번에는 Hook의 또 다른 기능중에 하나인 useEffect의 대해 알아보겠다.
useEffect는 함수형 컴포넌트에서 효과들을 실행할 때 쓰이며, 기존 클래스 컴포넌트의 라이프사이클 메서드들을 대체한다.
라이프사이클이란?
LifeCycle Method - componentDidMount, componentDidUpdate
메소드는 크게 두 종류로 나눠진다.
- will 메소드 : 어떠한 작업이 실행되기 직전에 호출
- did 메소드 : 어떠한 작업이 실행된 직후에 호출
생명주기 메소드에서는 Mount라는 단어가 등장하는데, 여기서 마운트는 리액트가 컴포넌트를 실제 DOM에 삽입하는 것 이다.
여기서 라이프 사이클의 대해 얘기할려면 너무 길어지기 때문에 따로 찾아보는 것을 추천한다!
그리하여 컴포넌트가 마운트 됐을 때 (처음 나타났을 때), 언마운트 됐을 때 (사라질 때), 그리고 업데이트 될 때 (특정 props가 바뀔 때) 특정 작업을 처리하는 방법에 대해 알아보겠다.
우선 UserList의 코드를 수정해준다.
UserList.js
import React, { useEffect } from 'react';
function User({ user, onRemove, onToggle }) {
useEffect(() => {
console.log('컴포넌트가 화면에 나타남');
return () => {
console.log('컴포넌트가 화면에서 사라짐');
};
}, []);
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를 사용할 때, 첫 번째 파라미터에는 함수, 두 번째 파라미터에서는 의존값이 들어있는 배열을 넣는다. 만약 두 번째 파라미터를 비우면, 컴포넌트가 처음 등장할때만 useEffect에 등록한 함수가 호출된다.
- function : 수행하고자 하는 작업
- deps : 배열 형태이며, 검사하고자 하는 특정 값을 넣는다.
그리고 재미있는 사실은 useEffect에서는 함수를 반환 할 수 있는데 이를 cleanup 함수라고 부른다.
cleanup 함수는 useEffect의 뒷정리를 해주는 역할을한다.
두 번째 파라미터 (dependency)가 비어있는 경우에 컴포넌트가 사라질 때 cleanup 함수가 호출된다.
화면을 확인하면...
코드를 작성하고 콘솔을 확인해보니, 새로운 항목을 추가해보고 제거도 해봤다.
컴포넌트가 마운트, 언마운트 될 때 주로 우리가 추가하는 작업
마운트 될 때
- props로 받은 값을 컴포넌트의 state로 설정
- 컴포넌트가 나타나면 외부 API (REST API)를 요청
- 라이브러리를 사용 (D3, Video.js 등)
- setInterval이나 setTimeout과 같은 작업 예약
언마운트 될 때
- setInterval, setTimeout을 사용해서 등록했던 작업을 제거할 때 즉, clearInterval이나 clearTimeout과 같은 작업
- 라이브러리 인스턴스를 만들었다면, 이 인스턴스를 제거
deps 에 특정 값 넣기
이번에는 deps에 특정 값을 넣어보겠다. deps에 특정 값을 넣게 된다면,
컴포넌트가 처음 마운트 될 때 호출되고, 지정한 값이 바뀔 때도 호출이 된다.
그리고, deps 안에 특정 값이 있다면 언마운트시에도 호출이되고, 값이 바뀌기 직전에도 호출된다.
다음과 같이 코드를 수정해보겠다.
UserList.js
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, 상태가 있다면, deps에 넣어주어야 한다. 이 것은 규칙이다!
위의 코드에서는 user라는 파라미터가 사용되었기 때문에 배열에 user를 넣어준다.
그리고 만약에 useEffect 안에서 사용하는 props이나 상태를 deps에 넣지 않게 되면은, useEffect 에 등록한 함수가 실행 될 때 최신 props 혹은 상태를 가르키지 않게 된다.
deps 파라미터를 생략하기
deps 파라미터를 생략한다면, 컴포넌트가 리렌더링 될 때마다 호출이된다.
밑에 있는 코드를 이용해서 확인해보자!
UserList.js
import React, { useEffect } from 'react';
function User({ user, onRemove, onToggle }) {
useEffect(() => {
console.log(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;
아까처럼 똑같이 먼저 등록하고 삭제해봤는데, 모든 항목들이 렌더링될 때마다 다같이 호출된다.
참고 : 벨로퍼트와 함께하는 모던 리액트
느낀점 :
- 오늘은 Hook의 라이프사이클을 책임지는 useEffect의 대해 알아봤다.
- 생각보다 이해하는데 시간이 걸렸고 댓글들을 확인하면서 내가 놓친 부분이 있는지 확인해봤다.
Author And Source
이 문제에 관하여(React 배움의 연속 #9), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@klucas/React-배움의-연속-9저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)