왜 useEffect 일까?
useEffect에서 "effect"가 의미하는 바는 무엇일까.
effect는 side effect 라는 함수형 프로그래밍 용어를 나타낸다.
side effect가 무엇인지 이해하려면 순수 함수의 개념을 이해 해야 한다.
대부분의 React 컴포넌트는 순수 함수로 만들어져 있다.
function MyReactComponent(){}
순수 함수 (pure function)
1. 함수의 return 값이 동일한 인수 (argument)에 대해 동일하다.
2. side effect가 없다. (외부의 상태를 변경하지 않는다)
대부분의 React 컴포넌트는 순수 함수이다. 즉, input을 받아 예측 가능한 JSX 리턴 값을 만들어 낸다.
JavaScript 함수에 대한 input은 인수 (argument)이다.
그러나 React 컴포넌트에 대한 입력은 Props이다.
export default function App(){
return <User name="John Doe" />
}
function User(props){
return <h1>{props.name}</h1>; //John Doe
}
위의 React 컴포넌트는 순수 함수이다. 왜냐하면 같은 input이 주어진다면 항상 같은 output를 return할 것이기 때문이다.
props로 name="Jone Doe"를 전달하면 output은 항상 Jone Doe가 된다.
순수 함수는 예측 가능하고, 신뢰할 수 있고, 테스트하기 쉽다.
반대로 함수 내의 구현 내용이 함수 외부에 영향을 끼치는 경우, 해당 함수는 side effect가 있다고 얘기한다.
여기서 side effect를 일으키는 함수를 예로 들어보면 Math.random() 처럼 랜덤으로 바뀌는 등 함수의 입력이 아닌 다른 값이 함수의 결과에 영향을 미치는 경우에 side effect를 일으킨다고 볼 수 있다.
반면, side effect를 일으키지 않는 순수 함수의 경우에는 오직 함수의 입력만이 함수의 결과에 영향을 주는 함수 이다.
React에서 side effect란 무엇인가?
side effect는 "외부 세계"와 함께 수행되기 때문에 예측할 수 없다.
무언가를 하기 위해 React 컴포넌트 외부에 도달해야 하는 경우 side effect를 수행한다.
그러나! side effect를 수행한 결과는 예측할 수 없다..
예를 들어 서버에 데이터를 요청한 경우, 요청이 실패하면 데이터가 아닌 500 상태 코드를 받을 수 있다.
아주 단순한 애플리케이션을 제외한 사실상 모든 애플리케이션은 어떤 방식으로든 side effect에 의존한다고 한다.
일반적인 side effect로는 다음과 같은 것들이 있다.
- 백엔드 서버에 API로 데이터 요청하기
- 브라우저 API와 상호작용 (document, window 직접 사용하기)
- setTimeout, setInterval 등 예측할 수 없는 타이밍 함수 사용
useEffect는 React 컴포넌트에서 이러한 side effect를 처리하는 방법을 제공하기 위해 존재한다.
예를 들어, 브라우저 탭의 title 메타 태그를 변경하려는 경우, 다음과 같이 컴포넌트 내에서 직접 변경할 수 있지만,
이렇게 해서는 안된다!
function User({name}){
document.title=name;
//This is a side effect. Don't do this in the componenty body!
return <h1>{name}</h1>;
}
컴포넌트 안에서 직접 side effect를 수행하는 경우, 컴포넌트의 렌더링에 방해가 된다.
side effect는 렌더링 과정과 분리되어야 한다.
side effect를 수행해야 하는 경우, 컴포넌트의 렌더링이 끝난 후 수행되어야 한다.
바로 이 기능을 useEffect가 제공한다!
=> useEffect는 우리가 외부 세계와 상호작용하면서 해당 컴포넌트의 렌더링이나 성능에는 영향을 미치지 않도록 만들어 주는 도구이다.
useEffect를 어떻게 사용하는가?
useEffect의 기본 문법은 다음과 같다.
//1. import useEffect
import {useEffect} from 'react';
function MyComponent(){
//2. call it above the returned JSX
//3. pass two argument to it: a function and an array
useEffect(()=>{},[]);
//return ...
}
컴포넌트 내에서 side effect를 수행하는 올바른 방법은 다음과 같다
1. useEffect를 import 한다.
2. 컴포넌트의 return 문 보다 위에 useEffect를 사용한다.
3. useEffect에 두 개의 인수를 전달한다. (1. 함수, 2. 배열)
import {useEffect} from 'react';
function User({name}){
useEffect(()=>{
document.title=name;
}, [name]);
return <h1>{name}</h1>
}
useEffect의 첫번째 인수로 전달한 함수는 콜백 함수 이다.
이 함수는 컴포넌트가 렌더링 된 이후에 호출된다.
이 함수에서 sideEffect를 한 개 에서 여러 개 까지 수행할 수 있다.
두번째 인수는 종속성 배열 (dependency array)이다.
이 배열은 side effect가 의존하는 모든 값을 포함해야 한다.
위의 예에서는 외부 범위 값인 name을 기반으로 제목을 변경하고 있으므로, name을 종속성 배열에 포함해야 한다.
이 배열이 하는 일은 렌더링과 렌더링 사이에 값(name)이 변경되었는지 확인하는것이다.
값이 변경되었다면 side effect 함수를 다시 실행할 것이다.
useEffect 함수는 리액트 컴포넌트가 렌더링 될 때마다 특정 작업을 실행할 수 있도록 하는 Hook이다
useEffect는 component가 mount 됐을때, unmount 됐을 때, update 됐을 때 특정 작업을 처리할 수 있다.
[React] Side effect(사이드 이펙트)란? | 부수 효과, useEffect (tistory.com)
'FrontEnd > React' 카테고리의 다른 글
[React] useEffect의 실행 시점 (1) | 2024.07.12 |
---|---|
[React] useState란? (0) | 2024.07.08 |