Front-End/React

[React] useEffect와 Side Effect

Voyage_dev 2022. 4. 19. 09:55

Rendering in React

  • React에서 함수 컴포넌트의 rendering이란 state, props를 기반으로 UI 요소를 그려내는 행위
  • 렌더링의 결과물은 UI 요소, 즉, 화면에 JSX 문법으로 무엇이 나타날지를 적어둔 컴포넌트들
    • 그러한 렌더링 결과물에 영향을 주는 요소가 state와 props

Side Effect

Side Effect는 함수가 실행되면서 함수 외부에 존재하는 값이나 상태를 변경시키는 등의 행위를 말한다. 즉, React 컴포넌트가 화면에 렌더링된 이후에 비동기로 처리되어야 하는 부수적인 효과들이라고 볼 수 있다

코드 예시

let count = 0

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

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

greetWithSideEffect()라는 함수는 이름을 받아 인삿말을 리턴하는 함수이다

실행하는 중간에 함수 외부 세계에 있는 count라는 변수를 조작하므로 함수의 결과값 이회의 다른 상태를 변경시키는 행위에 해당하기 때문에 Side Effect가 있다고 볼 수 있다

이러한 Side Effect는 React의 함수 컴포넌트에서도 일어날 수 있다. 함수 컴포넌트의 Side Effect는 state와 props를 받아서 UI를 그려내는 것 이외의 행위라고 할 수 있다

그렇다면 함수 컴포넌트에서의 Side Effect는 , 렌더링이 아니고 외부 세계에 영향을 주는 어떠한 행위이다

대표적으로 Data Fetching, DOM에 직접 접근, 구독과 같은 행위들이 있다 이들 모두 컴포넌트에서 꼭 필요한 대표적인 Side Effect들이다

Side Effect는 절차형 프로그래밍에서 흔히 존재하는 작업이었고 무조건 나쁜 패턴이라고 볼 수는 없다. 하지만 Side Effect는 프로그램을 읽기 어렵게 하고, 실행 상태를 예측하기 어렵게 하며 개발비용을 증가시킨다고 보기 때문에, 최근에는 선언형 프로그래밍에서 Side Effect를 최소화 하는 방향으로 변화고 있다. 왜나하면 함수는 전달받은 매개변수를 통해 연산을 수행하고 결과를 반환해야 하며 그 결과는 항상 일관되고 예측할 수 있어야 프로그램이 쉽고 단순하며 유지보수하기 쉬워지기 때문이다.

useEffect

React에서는 Side Effect 처리를 위해 useEffect()함수를 제공한다. 함수가 매개변수를 받아 결과를 생성하는 것과 무관한 외부의 상태를 변경하거나 상호작용해야 하는 코드는 useEffect() 함수를 통해 분리해야 한다.

함수 컴포넌트의 리턴 값은 UI 요소이고, state,props의 변화가 있을 때 마다 함수가 실행되기 때문에 렌더링 때마다 함수 body에 있는 로직이 실행된다는 뜻이다

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

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

위의 코드는 함수형 컴포넌트가 실행되고 결과를 생성하는 것과 무관한 document.title을 수정하고 있다. 이러한 코드는 작은 프로그램을 개발 할 때는 문제가 없겠지만, 다양한 개발자들이 대규모 프로그램을 협업 개발할 때 실행상태를 예측하기 힘들게 한다. 또한 렌더링과 무관한 로직이 렌더링 과정에서 실행되기 때문에 렌더링 자체에 영향을 줘 성능 상 악영향을 끼칠 수도 있다

React에서는 이러한 Side Effect 작업을 useEffect()를 통해서 분리할 수 있도록 지원한다.

공식 문서에서도 useEffect를 "React의 순수한 함수적인 세계에서 명령적인 세계로의 탈출구로 생각하세요" 라고 설명하고 있다. 여기서 "순수한 세계"란 렌더링(Input → Output)을 뜻하고, 렌더링 이외에 일으켜야 하는 Side Effect를 일으킬 탈출구로 useEffect를 사용하라는 의미이다

useEffect()를 통해서 Side Effect 코드를 등록할 수 있으며 React가 알아서 적절한 시점에 Side Effect 작업을 수행해 줄 것이다. 이러한 처리는 함수형 컴포넌트가 빠르게 렌더링 될 수 있게 도와주며, 프로그램을 복잡하게 만드는 Side Effect 영역을 함수와 분리할 수 있게 도와준다

import { useEffect } from 'react';

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

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

위와 같이 useEffect()를 사용하면 어떤 개발자라도 컴포넌트에 Side Effect가 포함된다는 것을 알 수 있다. React에서는 useEffect()에 등록된 Side Effect 코드를 최적화된 시점에 실행하기 때문에 컴포넌트의 실행속도를 개선하는데도 도움이 된다

 

출처 : 아래의 사이트들을 보면서 큰 공부 하였습니다

https://points.tistory.com/86

 

[React] useEffect()와 Side-Effect

useEffect()? React에서 제공하는 useEffect()는 Side-Effect를 처리하기 위해 사용한다고 합니다. 그렇다면 Side-Effect는 무엇일까요? 의료계에서 말하는 부작용의 의미는 아니고, 컴퓨터 공학에서 사용하는

points.tistory.com

https://www.daleseo.com/react-hooks-use-effect/

 

React Hooks: useEffect 사용법

Engineering Blog by Dale Seo

www.daleseo.com

https://ko.reactjs.org/docs/hooks-effect.html