리액트 - Lifecycle & useEffect()

Sungw__k·2022년 6월 28일
0
post-thumbnail

컴포넌트에는 Lifecycle이라는 개념이 있다.

컴포넌트는 생성(mount)되고 리랜더링(update)되며 삭제(unmount)된다.

우리는 이러한 순간들 마다 함수를 호출하거나 무언가를 실행할 수 있다.


"Detail 컴포넌트 등장 전에 이것좀 해줘"
"Detail 컴포넌트 사라지기 전에 이것좀 해줘"
"Detail 컴포넌트 업데이트 되고나서 이것좀 해줘"

이렇게 코드좀 실행해달라고 간섭할 수 있는데 간섭은 갈고리를 달아서 한다.

갈고리를 달고, 코드를 넣어주면 된다. 이 갈고리를 'Lifecycle hook' 이라고 부른다.

import {useState, useEffect} from 'react';

function Detail(){

  useEffect(()=>{
    //여기적은 코드는 컴포넌트 로드 & 업데이트 마다 실행됨
    console.log('안녕')
  });
  
  return (생략)
}

상단에서 useEffect import 하고, 컴포넌트 내에서 콜백함수 추가해서 안에 코드 적으면 이제 그 코드는 컴포넌트가 mount & update시 실행된다. 위 코드는 Detail 컴포넌트가 생성되거나 업리랜더링 될 때 마다 콘솔에 '안녕'이 출력될것이다.

물론 useEffect() 밖에 console.log를 적어도 컴포넌트가 mount & update 될 때마다 '안녕'이 출력된다. 이 둘의 차이는 useEffect안의 코드는 html이 모두 랜더링 된 후에 실행된다는 것이다. 즉 조금이라도 html 랜더링이 빠른 사이트를 원한다면 우선순위가 낮은 것들은 useEffect 안에 넣는것이 효과적이다.

useEffect(()=>{ 실행할코드 }, [count])

이렇게 대괄호를 콜백함수 뒤에 넣어주면 count라는 변수가 변할 때만 useEffect 안의 코드를 실행해달라는 뜻이다. 만약 대괄호를 비운채로 넣는다면 컴포넌트 mount시 1회 실행하고 그 뒤로는 실행하지 않는다.


useEffect(()=>{ 
  그 다음 실행됨 
  return ()=>{
    여기있는게 먼저실행됨
  }
}, [count])

useEffect 동작 전에 특정코드를 실행하고 싶으면 return ()=>{} 안에 넣을 수 있다. 그럼 useEffect 안에 있는 코드를 실행하기 전에 return ()=>{} 안에 있는 코드를 먼저 실행한다. 그리고 이걸 'clean up function'이라고 부른다. 예를들어 setTimeout 코드를 useEffect 안에서 쓰면 useEffect가 실행될 때 마다 타이머가 하나씩 생기는데 이가 반복되면 무수한 타이머가 생겨 버그를 야기한다. 이를 방지하려면 return ()=>{} 안에 타이머를 제거하는 clearTimer(타이머)를 작성하면 된다.

그래서 clean up function에는 타이머제거, socket 연결요청제거, ajax요청 중단 이런 코드를 많이 작성한다.


정리


1. 재랜더링마다 코드 실행

useEffect(()=>{ 실행할코드 })


2. mount시 1회만 실행 

useEffect(()=>{ 실행할코드 }, [])


3. useEffect 코드 실행 전에 실행

useEffect(()=>{ 
  return ()=>{
    실행할코드
  }
})


4. 컴포넌트 unmount시 1회 실행

useEffect(()=>{ 
  return ()=>{
    실행할코드
  }
}, [])


5. state1이 변경될 때만 실행

useEffect(()=>{ 
  실행할코드
}, [state1])

0개의 댓글