Front-end/React

[JUSTCODE] Basic Foundation - React useEffect

Hazel Han 2022. 10. 24. 22:05

Side Effect

"부수효과"로, 내가 원하던 결과 값 이외에 발생한 다른 결과를 의미한다.

 

ex)

let count = 0

function greetWithSideEffect(name) { // Input
	count = count + 1 // Side Effect!

	return `${name}님 안녕하세요!` // Output
}

내가 원하던 결과인 return문 외에 count가 하나씩 올라가는 효과를 얻었기 때문에 count는 Side Effect라고 할 수 있다.

 

만약, UI를 그려내는 렌더링이 원하던 결과였다면, UI를 그려내는 활동을 제외한 모든 것은 Side Effect라고 할 수 있다. 대표적으로는 data fetching, DOM에 직접 접근, 구독(setInterval)등이 있다.

 

이런 Side Effect는 함수의 body자리에서 실행하면 안된다. 함수는 state, props의 변화가 발생할 때 마다 실행되기 때문에 매 렌더링 때마다 body의 로직이 실행된다. 따라서 body자리에 Side Effect를 넣으면 렌더링 할 때마다 Side Effect 또한 실행되기 때문에 렌더링의 성능에 악영향을 끼칠 수 있기 때문이다.

 

 

useEffect

위에서 서술한 Side Effect의 영향 때문에 React에서 만들어진 것이 바로 useEffect Hook이다. useEffect는 Side Effect를 렌더링 이후에 실행되기 때문에 렌더링에 영향을 주지 않는다.

 

ex)

import { useEffect } from 'react';

function GreetWithSideEffect({ name }) { // Input
  useEffect(() => {
    // Good!
    document.title = `${name}님 안녕하세요!`; // Side Effect
  }, [name]);

  return <div>{`${name}님 안녕하세요!`}</div>; // Output
}

 

사용방법

import { useEffect } from "react"

// 사용법
useEffect( 실행시킬 동작, [ 타이밍 ] )
document.addEventListener("타이밍", 실행시킬 동작) // 추상화 한 예시

// 매 렌더링마다 Side Effect가 실행되어야 하는 경우
useEffect(() => {
  // Side Effect
})

// Side Effect가 첫 번째 렌더링 이후 한번 실행 되고,
// 이후 특정 값의 업데이트를 감지했을 때마다 실행되어야 하는 경우
useEffect(() => {
  // Side Effect
}, [value])

// Side Effect가 첫 번째 렌더링 이후 한번 실행 되고,
// 이후 어떤 값의 업데이트도 감지하지 않도록 해야 하는 경우
useEffect(() => {
  // Side Effect
}, [])

 

 

Clean up Effect

이전에 발생한 Side Effect를 없애고 싶을 때 사용.

 

사용방법

useEffect(() => {
	function handleScroll() {
		console.log(window.scrollY)
	}

	document.addEventListener("scroll", handleScroll)
	return () => {
		document.removeEventLisnter("scroll", handleScroll)
	}
}, [])

useEffect 안에 해당 로직을 없애는 동작을 넣어주면 된다.