[React]useEffect

LMH·2022년 11월 30일
0
post-thumbnail

useState가 Class 컴포넌트의 내부의 state를 대체할 수 있는 것 처럼 useEffect는 Class 컴포넌트에서 컴포넌트 생명주기를 관리하는 메소드를 대체할 수 있습니다.

메소드를 대체할 수 있다고 해서 완전히 동일하게 동작한다는 의미는 아닙니다. 대체할 수 메소드는 다음과 같습니다.

1. componentDidMount(컴포넌트가 렌더링된 직후)

2. componentDidUpdate(컴포넌트가 업데이트된 직 후)

3. componentWillUnmount(컴포넌트가 렌더링 되었다가 사라질 때)

예시로 확인해 보도록 하겠습니다. useEffect는 첫번째 인자로 콜백함수를 받고 두 번째 인자로 의존성 배열(dependency Array)를 받습니다.

useEffect 함수는 의존성 배열의 유무와 clean up 여부에 따라서 다른 시점에 호출 됩니다.

의존성 배열을 전달하지 않을 경우에는 컴포넌트가 렌더링(최초, 업데이트 될 경우) 될때 마다 호출 됩니다.

아래의 코드는 div 요소의 숫자가 무한하게 증가하는 코드입니다. 최초에 렌더링이 발생하면 useEffect 함수가 호출되어 num값이 1이 증가하게되고 num값의 변화로 인핸 useEffect가 다시 호출되는 작업이 반복적으로 일어나게 됩니다.

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

export default function example() {
const [num, setNum] = useState(0);

useEffect(() => {
    setNum(num+1)
	console.log("componentDidMount & componentDidUpdate")
})

  return ( 
    <div>{num}<div>
  )
}

useEffect를 사용할 때는 이렇게 불필요한 렌더링을 줄여야 합니다. 이 때 의존성 배열을 사용합니다. 아래의 코드를 보면 useEffect의 두번쨰 인자로 빈 배열을 전달했습니다. 이 경우에는 num값이 1로 증가하고 더 이상 렌더링이 되지 않습니다.

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

export default function example() {
const [num, setNum] = useState(0);

useEffect(() => {
    setNum(num+1)
	console.log("componentDidMount & componentDidUpdate")
}, [])

  return ( 
    <div>{num}<div>
  )
}

의존성 배열에 num을 전달하면 무슨일이 발생할까요? 처음 작성한 코드처럼 useEffect가 무한히 호출됩니다. 여기서 의존성 배열의 역할을 알 수 있습니다. 의존성 배열에 명기한 state값이 업데이트 될 경우 useEffect를 호출하게 됩니다.

의존성 배열에는 1개 이상의 여러 state를 추가 할 수 있습니다.

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

export default function example() {
const [num, setNum] = useState(0);

useEffect(() => {
    setNum(num+1)
	console.log("componentDidMount & componentDidUpdate by num")
}, [num])

  return ( 
    <div>{num}<div>
  )
}

위 의 예시에서 useEffect를 사용하는 것은 componentDidMount, componentDidUpdate 메소드가 호출되는 것과 같은 효과를 얻을 수 있다는 것을 알 수 있었습니다.

그렇다면 componentWillUnmount는 어떻게 구현할 수 있을까요? 바로 이 때 클린업이라는 개념이 등장합니다. useEffect가 전달받는 콜백함수에서 또 다른 함수를 리턴해주면 됩니다.

리턴되는 함수 블록내부에서는 주로 useEffect에서 사용한 로직을 원래되로 되돌리기 위해 사용합니다. 예를들어, useEffect에서 추가한 이벤트 리스너를 제거한다던지 말이죠.

다음 useEffect 함수가 호출되면, 실행되기 직전에 이전 클린업 부분의 코드가 먼저 실행됩니다. 이 경우 state값은 새로 호출된 useEffect가 실행되기 이전 값을 가집니다.

이전 state값을 가지는 것을 보아 componentWillUnmount와는 동작 방식이 다르다는 것을 알 수 있습니다.

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

export default function example() {
const [num, setNum] = useState(0);

useEffect(() => {
    setNum(num+1)
	console.log("componentDidMount & componentDidUpdate")
  return () => {
    console.log("clean up")
    // cleanup
  	// componentWillUnmount
  }
}, [num])

  return ( 
    <div>{num}<div>
  )
}
profile
새로운 것을 기록하고 복습하는 공간입니다.

0개의 댓글