이전 글중에 순수함수를 알아보면서 부수효과 (side effect)에 대해서 알아본 적이 있었다.
리액트에서도 이런 부수효과와 관련된 기능이 존재한다.
(자바스크립트에서의 사이드이펙트와 리액트에서의 사이드이펙트는 살짝 느낌이 다르다)
이 기능은 앞서 알아본 useState와 마찬가지로 리액트에서 제공하는 리액트 훅이다.
이 글을 시작으로 중요한 리액트 훅 3 + 1 개를 알아보면서 리액트에 대해서 더 깊게 이해해보자
이 글에서 알아볼 것
- React에서의 Side Effect
- useEffect
1. React에서의 Side Effect
자바스크립트에서의 사이드 이펙트는 함수의 동작으로 인해 외부가 바뀌는 것을 말했었다.
(https://joseph0926.tistory.com/21)
리액트에서의 사이드 이펙트는 조금 느낌이 다르다
- 리액트의 주요 임무는 UI를 렌더링하는 것과, state 변화등에 반응하여 코드를 재평가하는 것이다.
- 이러한 주요 임무 외, 일어나는 일들을 사이드 이펙트라 한다.
- 예를들어, HTTP 요청, 데이터 저장하는것등의 작업,
- 어떤 액션에 대한 응답으로 실행되는 액션이 존재하는 경우등을 말한다
- 이러한 작업들은 리액트와 직접적으로 관련되어있지 않다. = 이런 작업을 하기 위해 리액트를 사용하는 것이 아니다.
- 따라서, 이런 작업들은 일반적으로 컴포넌트 함수 평가의 밖에서 일어나야 한다.
- 즉, 사이드 이펙트는 직접적으로 컴포넌트 함수에 들어가서는 안된다
- 때문에 이러한 사이드 이펙트 작업을 전담하는 기술이 필요한데, 그것이 바로 useEffect 훅이다.
2. useEffect
- useEffect 구조
- useEffect(함수, [의존성])
- 함수 -> 오직 지정된 의존성이 변경된 경우, 모든 컴포넌트 평가 후에 실행되는 함수다
- 의존성 -> 의존성들이 배열에 있는 형태이다. 이러한 의존성들이 변경될때마다 함수가 실행된다
- 만약, 의존성중에 변경된것이 없다면 useEffect는 실행되지 않는다.
- 만약, 의존성이 빈배열로 설정한다면 웹이 실행될때 처음 한번만 딱 실행된다
- useEffect(함수, [의존성])
- useEffect 의존성
- useEffect 안에 정의되어있는 사이드 이펙트 함수에서 사용되는 것을 의존성으로 추가하면 된다.
- 예를들어,
useEffect(() => {
setFormIsValid(enteredEmail.includes("@") && enteredPassword.trim().length > 6);
}, []);
- 위의 코드에서는 무엇을 의존성으로 추가해야할까?
- enteredEmail, enteredPassword이다
- 이때 들수있는 의문점은 setFormIsValid는 왜 추가하지 않는가이다.
- setFormIsValid은 useState 업데이트함수고, 이러한 업데이트 함수는 리액트에 의해 절대 변경되지 않는다는 것을 보장받기 때문에 생략가능하다.
- 그러면 의존성으로 추가해서는 안되는 것들은 뭐가 있을까?
- 상태 업데이트 기능을 추가할 필요가 없다
- setFormIsValid를 생략하는 이유와 동일
- 내장 API 또는 내장 함수를 추가할 필요가 없다.
- 이러한 것들은 리액트와 관련이 없이 변경되지 않는다
- 함수 외부에서 정의한 변수나 함수를 추가할 필요가 없다
- 이러한 함수 또는 변수도 구성 요소 함수 내부에서 생성되지 않으므로 변경해도 구성 요소에 영향을 주지 않는다.
- 리액트 처음에 살펴본 state의 작동원리를 기억해보자..그때도 일반변수를 변경한다해도 컴포넌트 재평가가 일어나지 않은 것과 비슷하다
- 이러한 함수 또는 변수도 구성 요소 함수 내부에서 생성되지 않으므로 변경해도 구성 요소에 영향을 주지 않는다.
- 상태 업데이트 기능을 추가할 필요가 없다
- useEffect 클린업 함수
- 위의 코드를 보자, 의존성으로 enteredEmail, enteredPassword을 설정하였기 때문에, 키입력이 하나하나 트리거될때마다 useEffect는 작동할 것이다. (ref가 아닌 state를 통해 입력을 컨트롤 했다고 가정하자)
- 그러면 useEffect 안의 setFormIsValid 업데이트 함수가 실행될텐데, 이는 state에서 배웟듯이 state가 업데이트되면, 리액트는 재평가를 실행한다
- 즉, 키 입력 하나하나 마다 재평가가 실행될 수 있다.
- 성능 이슈가 발생한다.
- 이때 사용하는것이 Cleanup 함수다
- 즉, 키 입력 하나하나 마다 재평가가 실행될 수 있다.
- useEffect는 첫번째 인자(함수)에서 return 할수있고, 이때 함수도 return이 가능하다
- 이 return되는 함수를 보통 Cleanup 함수라 부른다.
- 이러한 클린업 함수는 처음 실행될때를 제외하고는 사이드이펙트 함수보다 먼저 실행된다 (첫 실행때는 클린업함수 실행안됨)
- 말로는 무슨 느낌인지 잘 안와닿을것이다. 예시를 통해 이해해보자
useEffect(() => {
const timerHandler = setTimeout(() => {
console.log("사이드 이펙트 함수");
setFormIsValid(enteredEmail.includes("@") && enteredPassword.trim().length > 6);
}, 500);
return () => {
console.log("클린업 함수");
clearTimeout(timerHandler);
};
}, [setFormIsValid, enteredEmail, enteredPassword]);
- 클린업 함수가 없었다면, useEffect의 함수가 사진에 클린업함수처럼 여러번 찍혔을 것이다.
- 하지만 보이는대로 클린업 함수를 통해 이를 방지해준다.
지금까지 글을 정리하면서 살펴본 리액트 훅은 2개다
useState, useEffect
정말정말 중요한 역할들을 하는 훅이고, 반드시 완벽한 이해가 필요하다.
자세한 활용은 나중에 StepByStep 프로젝트등의 프로젝트에서 다뤄보도록하겠다.
'OLD > React' 카테고리의 다른 글
[React] React Context (useContext) (0) | 2023.03.03 |
---|---|
[React] React useReducer 훅 (0) | 2023.03.01 |
[React] React에서 사용자 입력을 컨트롤 하는 두 가지 방법 (state vs ref) (0) | 2023.02.26 |
[React] React 여러 기능들 (Fragment, Portal) (0) | 2023.02.25 |
[React] React "key" prop (react에서 배열 활용 시 발생하는 Warning 해결하기) (0) | 2023.02.24 |