2 분 소요

Side Effect

Rendering in React

  • React에서 rendering은 state, props를 기반으로 ui 요소를 그려내는 행위이다.
  • Input (state, props)에 따라 다른 UI를 표현하는 함수와도 구조적으로 동일하다.

Side Effect

  • 부수효과라고 부른다.

  • 함수가 어떤 동작을 할 때 input, output 이외의 다른 값을 조작한다면, 이 함수에는 sideEffect가 있다고 표현한다.

  • 대표적으로 Data Fetching, DOM에 직접 접근, 구독(setInterval(), setTimeout())과 같은 행위들이 있다.

  • setInterval(() ⇒ {}, n); // n ms마다 해당 콜백을 실행함

    setTimeout(() ⇒ {}, n); // n ms 뒤에 해당 콜백을 실행함

function greetWithSideEffect({ name }) { // Input
  // Bad!
  document.title = `${name}님 안녕하세요!`; // Side Effect

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

Side Effect를 함수의 body에서 실행시키면 안된다.

State,props의 변화가 있을 때마다 함수가 실행되는데 매 렌더링 때마다 함수 body에 있는 로직이 실행된다.

렌더링과 무관한 로직이 렌더링 과정에서 실행되기 때문에 렌더링 자체에 영향을 줘 성능 상 악영향을 끼칠 수도 있다.

따라서 이러한 side Effect를 일으키기 적절한 장소로 useEffect hook을 제공한다.

side Effect를 아래 방식처럼 사용해야 한다.

import { useEffect } from 'react';

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

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

useEffect

사용법

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

Effect 이후 일어나는 clean up Effect 이다.

전에 일어난 side Effect를 정리할 필요가 있을 때 사용합니다.


만약 우리가 팝업창을 열었을 때 마우스의 x,y 좌표를 계산하여 화면에 출력한다고 하자

그러면 우리가 팝업창을 열었을 때는 side Effect가 발생하지만

팝업창을 닫은 이후에도 side Effect가 발생할 필요가 없기 때문에

Effect를 정리해줘야 한다.

사용법

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

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

주의점은 컴포넌트가 사라지는 시점에 cleanup Effect가 실행되는게 아니고

다음 Effect가 일어나기 전에, cleanup Effect가 실행되는 것입니다.

예시)

const App = () => {
  const [count, setCount] = useState(0);

  console.log("render", count);

  useEffect(() => {
    console.log("useEffect Callback", count);
    return () => {
			console.log("cleanUp", count);
		});
  }, [count]);

  return <div onClick={() => setCount(count + 1)}>Hello</div>;
};

render, 0 useEffect Callback, 0

// 클릭

render, 1

cleanUp, 0

useEffect Callback, 1

// 클릭

render, 2

cleanup, 1

useEffect Callback, 2

카테고리:

업데이트:

댓글남기기