Lifecycle & useEffect

fe.syhan·2023년 11월 1일
0

React basic

목록 보기
13/17
post-thumbnail

Lifecycle


컴포넌트는

  1. 생성이 될 수도 있고(mount)
  2. 재렌더링이 될 수도 있고(update)
  3. 삭제가 될 수도 있다.(unmount)

라이프사이클을 배우는 이유는 컴포넌트 인생 중간중간에 간섭할 수 있기 때문이다.

간섭이란 컴포넌트가 장착될 때 , 업데이트 될 때 등 특정 코드를 실행할 수 있다는 뜻이다.

Lifecycle hook

“컴포넌트 등장 전에 이것 좀 해 줘”, “컴포넌트가 사라지기 전에 이것 좀 해 줘” 등 과 같이 코드 실행을 간섭하도록 갈고리(hook)를 달아 줄 수 있다.

class Detail2 extends React.Component {
  componentDidMount(){
    //Detail2 컴포넌트가 로드되고나서 실행할 코드
  }
  componentDidUpdate(){
    //Detail2 컴포넌트가 업데이트 되고나서 실행할 코드
  }
  componentWillUnmount(){
    //Detail2 컴포넌트가 삭제되기전에 실행할 코드
  }
}

예전 class 문법을 사용할 당시 특정 훅을 사용했다.

useEffect

근래엔 useEffect()를 활용해 훅을 작성한다.

import {useState, useEffect} from 'react';

function Detail(){

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

useEffect() 안의 콜백 함수는 컴포넌트가 mount&update시 실행 된다.

<React.StrictMode>

위 훅의 console.log('안녕') 이 2번 출력 되는걸 알 수 있는데, 이는 디버깅용으로 2번 출력 되는 것이다.

이를 원하지 않는다면 index.js 파일에서 <React.StrictMode> 를 제거해 주면 된다.

실행 시점

console.log(’1’)useEffect() 바깥에 적어도 mount & update 시 실행이 된다.

function Detail(){

  useEffect(()=>{
   
  });
		console.log('안녕')
  return (
		// 생략
	)
}

ㅋ컴포넌트가 mount, update시 function 안에 있는 코드도 다시 읽고 지나가기 때문이다.

그렇더면 useEffect는 왜 쓰는걸까?

useEffect 안에 적은 코드는 html 렌더링 이후에 동작한다.

아래 코드는 반복문을 실행하고 하단의 html을 렌더링해줄 것이다.

function Detail(){

  (반복문 10억번 돌리는 코드)

  return (생략)
}

반면,

function Detail(){

  useEffect(()=>{
    (반복문 10억번 돌리는 코드)
  });
  
  return (생략)
}

html을 렌더링하고 반복문을 돌릴 것이다.

이는 코드의 실행 시점을 조절해 html 렌더링이 조금 더 빠른 상황이 연출될 것이다.

Side Effect

함수의 핵심기능 외에 부가적인 기능들을 프로그래밍 용어로 side effect라고 하는데 useEffect도 여기에 차용하였다.

컴포넌트의 핵심 기능은 html렌더링이기 떄문에

그 외에 잡다한 오래 걸리는 반복 연산, 서버에서 데이터 가져오기, 타이머 등 부수적인 것들을 useEffect안에 작성 한다.

useEffect(fnc, [ ])

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

useEffect() 의 둘째 파라미터로 [] 가 올 수 있는데

변수나 state가 들어간다.

[ ]에 있는 변수나 state가 변경 될 때만 useEffect 안의 코드가 실행 된다.

[ ] 안이 공백이라면, 컴포넌트 mount시(로드 시) 1회 실행하고 재실행 하지 않는다.

clean up function

useEffect가 동작하기 전에 특정 코드를 실행이 가능하다.

useEffect(() => {
	console.log(2) // ------ (2)
	return () => {
		console.log(1) // ---- (1)
	}
}, [])

return () ⇒ {} 안에 있는 1을 먼저 출력하고 다음으로 2가 출력이 된다.

가령, useEffect() 안에 setTimeOut() 가 있을 경우 컴포넌트가 마운트 될 때 마다 실행이 되는데 잘못 된 코드로 인해 무수히 많은 타이머가 생성이 될 수도 있다.

useEffect() 에서 타이머를 만들기 전에 기존의 타이머를 제거하는 코드를 짠다면 미연에 이를 방지할 수 있을 것이다.

useEffect(()=>{ 
  let a = setTimeout(()=>{ setAlert(false) }, 2000)
  return ()=>{
    clearTimeout(a)
  }
}, [])
💡 1. clean up function에는 타이머제거, socket 연결 요청제거, ajax요청 중단 등의 코드를 작성한다. 2. 컴포넌트 unmount 시 clean up function 내부가 1회 실행 된다.

0개의 댓글