본문 바로가기

Frontend/React

[React] Hook - useEffect

안녕하세요.

오늘은 React Hook 기능 중 하나인 'useEffect'에 대해 알아보도록 하겠습니다.

useEffect은 렌더링 이후에 추가적인 작업을 처리하기 위해 자주 사용하는데요. 

 

이 추가적인 작업(side effects)은 크게 두 종류로 나눌 수 있습니다.

1. Cleanup이 필요하지 않은 것

2. 메모리 누수를 방지하기 위해 Cleanup이 필요한 것 

 

*side effect란? 함수가 실행되면서 함수 외부에 존재하는 값이나 상태를 변경시키는 등의 행위

                   (ex. 데이터 Fetch, DOM 요소 변경 등등, 외부 자원 사용)

 

먼저 Cleanup이 필요하지 않은 경우에 대해 알아보겠습니다.

아래 코드는 DOM을 업데이트 한 후에 탭 제목(document.title)을 변경해줍니다. 

import React, {useState, useEffect} from 'react';

function Example(){
	const [count, setCount] = useState();
    
    useEffect(()=>{
    	document.title = `You clicked ${count} times`;
    });
	
	return (
    	<div>
        	<p>You clicked {count} times</p>
        	<button onClick{()=>setCount(count+1)}>
            	Click me
            </button>
        </div>
    
    )
}

탭 제목을 변경한 후에 추가로 할 작업이 없기 때문에 Cleanup이 필요하지 않습니다.

*useEffect를 component 안에서 사용하는 이유 : component 안에서 사용하면 state나 prop에 바로 접근할 수 있기 때문입니다. 

 

외부 자원을 사용할 때는 메모리 누수를 피하기 위해 Cleanup이 필요합니다.

아래 예제 코드를 봅시다.

import React, {useState, useEffect} from 'react';

function FriendStatus(props){
	const [isOnline, setIsOnline] = useState(null);
    
    useEffect(()=>{
    	function handleStatusChange(status){
        	setIsOnline(status.isOnline);
        }
        
        ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
        //Specify how to clean up after this effect
        return function cleanUp() {
        	ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
        };
    });
    
    if(isOnline === null){
    	return 'Loading...';
    }
    
    return isOnline? 'Online':'Offline';
}

위 코드에서는 ChatAPI을 사용하여 친구의 온라인 상태를 조회하고 있습니다. 온라인 상태를 조회한 후 자원을 해제하기 위해 useEffect에서 함수를 리턴합니다.

useEffect 에서 함수를 리턴하면, React가 렌더링을 끝낸 후 해당 함수를 실행하여 자원을 해제합니다.

 

useEffect 함수는 렌더링 후에 매번 호출되므로 성능적인 이슈에 대해 고민하시는 분들도 있을 겁니다.

성능 이슈 해결을 위하여 useEffect 함수를 건너뛰는 방법도 있습니다.

 

아래의 코드와 같이 useEffect의 두 번째 인자에 배열을 넘겨주어, 배열 안의 값이 바뀌지 않으면 실행되지 않도록 설정할 수 있습니다. 

(눈치채신 분들도 계시겠지만, useEffect 두 번째 인자에 빈 배열을 넣어주면 마운트될 때 처음 한 번만 실행되고

 아무 값도 전달하지 않으면 렌더링 할 때마다 실행됩니다.)

useEffect(()=>{
	document.title = `You clicked ${count} times`;
},[count]);

count 값이 바뀌지 않으면 useEffect는 실행되지 않게 됩니다. 이전 상태의 값과 비교하여 같으면 실행하지 않고, 다르면 실행하는 구조입니다.

 

오늘은 useEffect 함수에 대해 알아보았는데요, 혹시 궁금한 점이 있으시면 댓글 남겨주시길 바랍니다 :)

 

출처 : https://reactjs.org/docs/hooks-effect.html

         https://points.tistory.com/86