React/Velopert's React

[React] Study #15 | useEffect

yevdev 2021. 10. 8. 09:57

이번 포스팅은 useEffect라는 Hook을 사용하여 컴포넌트가 마운트 됐을 때 (처음 나타났을 때), 언마운트 됐을 때(사라질때), 그리고 업데이트 될때 (특정 props가 바뀔 때) 특정 작업을 처리하는 방법에 대한 것이다!

 

1️⃣ 마운트 / 언마운트

import React, {useEffect} from 'react' // useEffect 불러오기

function User({user, onRemove, onToggle}) {

    // useEffect 사용!
    useEffect(() => {
        console.log('컴포넌트가 화면에 나타남');
        return() => {
            console.log('컴포넌트가 화면에서 사라짐');
        }
    },[]);

    return(
        <div>
            <span
                style={{ 
                    cursor: 'pointer',
                    color: user.active ? 'green':'black',
                }}

                onClick={()=>onToggle(user.id)}
                >{user.username}</span>
            &nbsp;
            <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 의 사용

  • 첫번째 파라미터 : 함수
  • 두번째 파라미터 : 의존값이 들어있는 배열 (deps)
    • 만약 deps 배열을 비우게 된다면, 컴포넌트가 처음 나타날 때만 useEffect에 등록한 함수가 호출된다.

💡cleanup 함수

  • useEffect에서는 함수를 반환할 수 있는데, 이를 cleanup 함수라고 부른다.
  • useEffect안에서 return 할 때 실행된다.
  • useEffect에 대한 뒷정리를 해준다. -> state에서 값을 지울 때 실행된다.
  • deps가 비어있는 경우에는 컴포넌트가 사라질 때 cleanup함수가 호출된다.

출력 : 사람들을 추가하고 삭제하면 콘솔의 메시지가 바뀐다.

🔨마운트 시에 하는 작업들

  • props로 받은 값을 컴포넌트의 로컬 상태로 설정
  • 외부 API 요청 (REST API등,,)
  • 라이브러리 사용 (D3, Video.js 등,,)
  • setInterval을 통한 반복작업 혹은 setTimeout을 통한 작업 예약

🔨언마운트 시에 하는 작업들

  • setInterval, setTimeout 을 사용하여 등록한 작업들 clear 하기 ( clearInterval, clearTimeout)
  • 라이브러리 인스턴스 제거

 

2️⃣ deps에 특정 값 넣기

  • deps에 특정 값을 넣게 된다면, 컴포넌트가 처음 마운트 될 때에도 호출이 되고, 지정한 값이 바뀔 때에도 호출이 된다.
  • 그리고 deps 안에 특정 값이 있다면 언마운트 시에도 호출이 되고, 값이 바뀌기 직전에도 호출이 된다.
  • deps에 값이 없다면 useEffect가 최신 값을 가리키지 않게 되고 컴포넌트가 리렌더링 될 때마다 호출이 된다.
  • useEffect 안에서 사용하는 상태나 props가 잇다면 useEffect의 deps에 넣어주어야한다.
  • 만약 useEffect 안에서 사용하는 상태나 props를 deps에 넣지 않게 된다면 useEffect에 등록한 함수가 실행될 때 최신 props 상태를 가르키지 않게 된다.

userList.js의 useEffect 부분을 수정해보자

// user 배열을 deps로 넣어주기
    useEffect(() => {
        console.log('컴포넌트가 화면에 나타남');
        console.log(user);
        return() => {
            console.log('컴포넌트가 화면에서 사라짐');
            console.log(user);
        }
    },[user]);

항목을 추가하고 삭제할 때마다 최신 props 상태가 보인다

 

3️⃣ deps 파라미터 생략해보기

  • deps 파라미터를 생략한다면, 컴포넌트가 리렌더링 될 때마다 호출이 된다.
    useEffect(() => {
        console.log(user);
    });

id=3을 지웠을 때 출력결과

 

 

💡deps 다시 한번 간략 정리 

  1. deps에 빈 배열
    • 처음 컴포넌트 마운트 됐을 때 useEffect 내 함수 호출
    • 컴포넌트 언마운트 될 때 cleanup 함수 호출
  2. deps에 의존 값 존재
    • 처음 컴포넌트 마운트 됐을 때 useEffect 내 함수호출
    • 의존 값이 업데이트 됐을 때 useEffect 내 함수 호출
    • 컴포넌트 언마운트 될 때 cleanup 함수 호출
  3. 아예 파라미터를 안 넣었을 경우
    • 그냥 리렌더링 될 때마다 함수 호출

 

➕ 리액트 컴포넌트의 리렌더링

  • 기본적으로 부모 컴포넌트가 리렌더링되면 자식 컴포넌트 또한 리렌더링 , 바뀐내용이 없다하더라도!
  • 물론, 실제 DOM에 변화가 반영되는 것은 바뀐 내용이 있는 컴포넌트에만 해당
  • 하지만, Virtual DOM에는 모든 것을 다 렌더링 하고 잇음.

 


Reference

https://react.vlpt.us/basic/16-useEffect.html