개발일지

Lifecycle 과 useEffect 본문

React

Lifecycle 과 useEffect

kosssshhhh 2023. 2. 26. 22:45

컴포넌트의 Lifecycle 을 배우는 이유는 componentDidMount() 등 유용한 Lifecycle 함수들을 쓰기 위해서이다. 

 

요즘은 간편한 useEffect() 라는 react hook 을 많이 사용한다. 

 

 

 

 

 

 

컴포넌트의 Lifecycle

 

컴포넌트는 

 

1. 생성 될 수도 있고 (mount)

2. 재렌더링 될 수도 있고 (update)

3. 삭제될 수도 있다. (unmount)

 

컴포넌트의 lifecycle 을 배우는 이유는 컴포넌트 lifecycle 중간중간에 간섭할 수 있기 때문이다. 

 

컴포넌트가 장착될 때 특정 코드를 실행할 수도 있고, 컴포넌트 업데이트 될 때 특정 코드를 실행할 수도 있다. 

 

이러한 방법으로 여러 기능들을 개발할 수 있다. 

 

 

 

 

 

 

 

예전 React 에서 Lifecycle Hook 쓰는 법

 

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

 

예전에는 class 문법으로 컴포넌트를 만들어주었다. 

 

그 경우엔 안에 함수안에서 실행하고싶은 코드를 작성하여 코드를 실행시킬 수 있다. 

 

 

 

 

 

요즘 React 에서 Lifecycle Hook 쓰는 법

 

import { useState, useEffect } from 'react';

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

 

상단에 useEffect import 해준 후, 

콜백함수 추가해서 안에 코드 작성하면 해당 코드는 컴포넌트가 mount & update 시 실행된다. 

이것이 Lifecycle Hook

 

 

 

 

 

 

 

그런데 useEffect 밖에서 코드 적어도 똑같은 결과

 

사실 useEffect 밖에 적어도 똑같이 컴포넌트 mount & update 시 실행된다. 

 

컴포넌트가 재렌더링 시 function 안에 있던 코드들도 다시 읽고 지나가서 그렇다. 

그럼 useEffect 는 무슨 용도일까

 

 

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

 

예를들어 시간이 굉장히 오래 걸리는 코드가 있다고 가정하자.

 

 

function Detail(){
	(반복문 100000000번 돌리는 코드)
    return (생략)
}

위와같이 코드를 짜게되면 반복문을 많이 돌린 후, 하단 return 문의 html 을 보여준다. 

 

 

function Detail(){
  
  useEffect(()=>{
    (반복문 100000000 돌리는 코드)
  });
  
  return (생략)
}

 

하지만 useEffect 를 사용하면 html 보여주고 나서 반복문을 돌려준다.

 

이런 식으로 코드의 실행 시점을 조절할 수 있기 때문에 조금이라도 html 렌더링이 빠른 페이지를 원하면, 쓸데 없는 (반복문 많이 돌리기) 코드들은 useEffect 안에 넣어서 사용하는 것이 좋다. 

 

오래걸리는 반복연산, 서버에서 데이터 가져오는 작업, 타이머 달기 등

이런 코드들은 useEffect 안에 많이 적는다. 

 

 

 

 

 

 

useEffect 에 넣을 수 있는 실행조건

 

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

 

useEffect() 의 두번째 파라미터로 [] 를 넣을 수 있는데, 거기에 변수나 state 같은 것들을 넣어줄 수 있다. 

위와 같이 작성하면 [] 에 있는 변수나 state 가 변할 때만 useEffect 안의 코드를 실행해준다. 

 

따라서 위의 코드는 count 라는 변수가 변할 때만 안의 코드가 실행된다. 

 

[] 안에는 state 변수를 여러 개 넣어줄 수도 있다. 

 

 

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

위처럼 [] 안에 아무것도 넣지 않으면 컴포넌트 mount 시 (로드 시)  한번만 실행해준다.

 

 

 

 

 

clean up function

 

useEffect 동작하기 전에 특정 코드를 실행시키고 싶으면

return () => {} 안에 넣어주면 된다. 

 

useEffect(()=>{
	//그 다음 실행
    return ()=>{
    	//여기 먼저 실행
    }
}, []);

 

useEffect 안에 있는 코드를 실행하기 전에 return 함수 안에 있는 코드를 먼저 실행해준다. 

 

setTimeout 함수의 경우

setTimeout() 쓸 때마다 브라우저 안에 타이머가 하나 생긴다. 근데 useEffect 안에 작성했기 때문에 컴포넌트가 mount 될 때마다 실행된다. 

 

코드를 잘못 짜게 되면 타이머가 100개, 1000개 이상하게 생길 수 있다. 

 

따라서, 이런 버그를 미리 방지하기 위해서 useEffect 에서 타이머를 만들기 전에 기존 타이머를 제거하라고 코드 쓰면 되는데, 이럴때 return ()=>{} 안에 짜준다. 

 

 

useEffect(()=>{
	let a = setTimeout(()=>{
    	setAlert(false);
    }, 2000);
    
    return ()=>{
    	clearTimeout(a);
    }
})

타이머를 제거해주고 싶다면, clearTimeout(타이머) 이런식으로 작성해준다. 

타이머 장착하기 전에 기존 타이머가 있으면 제거해준다. 

 

  • clean up function 에는 타이머제거, socket 연결요청제거, ajax 요청 중단 등.. 이런 코드를 많이 작성해준다. 
  • 컴포넌트 unmount 시에도 clean up function 안에 있던 게 1회 실행된다. 

 

 

 

1. 재렌더링 할 때마다 코드 실행 가능

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

 

2. 컴포넌트 mount 시 (로드 시) 1회만 실행 가능

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

 

3. useEffect 안의 코드 실행 전에 항상 실행

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

 

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

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

 

5. state 이 변경될 때만 실행

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

'React' 카테고리의 다른 글

Context API  (0) 2023.03.07
Ajax 요청  (0) 2023.03.07
React Router (navigate, nested routes, outlet), useParams  (0) 2023.02.25
React Router  (0) 2023.02.17
export / import  (0) 2023.02.17