Side Effect 와 useEffect

JJ_Dean·2023년 1월 3일
0

React

목록 보기
12/14
post-thumbnail

Side Effect란?

사이드 이팩트란 애플리케이션에서 일어나는 모든 것을 뜻한다.

우리는 서비스를 이용하면서 버튼 클릭, 텍스트 입력 등등 여러 행동으로 웹 사이트와 상호 작용한다. 이때 상호작용을 위한 행동이 사이드 이팩트이다.

또 HTTP 리퀘스트 보내기, 브라우저 저장소 (예: 로컬 스토리지, 쿠키) 에 정보 저장하기, 타이머 설정 등의 행동도 사이드 이팩트이다.
이때 HTTP 리퀘스트의 응답으로 state를 변경한다면 무한 루프로 빠질 수 있다.

컴포넌트(함수)가 실행된다. ➡
함수 안에서 http 리퀘스트를 보낸다. ➡
http 리퀘스트의 응답으로 state를 변경한다. ➡
state가 변경됨에 따라 다시 함수가 실행된다. ➡
위 과정이 반복되며 무한 루프에 빠진다.

이런 문제를 해결하고자 즉 사이드 이팩트를 처리하기 위해 useEffect() 라는 React Hook을 사용한다.

useEffect()

useEffect의 사용 방법은 다음과 같다.

import React, { useEffect } from 'react';

useEffect(()=> {실행 될 함수}, [의존값이 들어있는 배열]);

useEffect를 react로 부터 import 받는다.
함수는 실행 될 함수이다. 이곳에 사이드 이팩트 코드가 들어간다.
의존할 것들로 구성된 배열의 값이 변경 될 때마다 실행 될 함수가 실행된다.
이후 컴포넌트가 재실행 되더라도 useEffect는 재실행되지 않는다.
배열의 값이 변경되지 않으면 useEffect는 실행되지 않는다.

useEffect 특징

  • 컴포넌트 실행 후 실행된다.
    - 즉 JSX 코드가 실행 된 후 useEffect 함수가 실행된다.
  • 처음 애플리케이션이 실행될 때 파라미터로 받은 이펙트 함수가 실행된다.
  • 이후 특정 요소가 변경될 때만 파라미터로 받은 이펙트 함수를 실행할 수 있다.

사용해보자

기본적인 기능

const [idState, setIdState] = useState('');

useEffect(() => {
  console.log('idState 값이 바뀔 때마다 실행 => ' + idState);
}, [idState]);

setIdState('아이스 아메리카노'); 
// idState 값이 바뀔 때마다 실행 => 아이스 아메리카노

idState의 값이 바뀌게 되면 useEffect에선 이 변화를 감지하여 파라미터로 받은 이펙트 함수를 실행한다.

애플리케이션을 처음 실행할 때만 사용하고 싶은 기능

useEffect(() => {
  console.log('처음 실행 후 다신 실행 안된다.');
}, []);

의존값이 들어갈 배열을 비워두면 애플리케이션이 처음 실행될 때만 파라미터의 이펙트 함수가 실행된다.

재평가 될 때마다 실행되는 기능

useEffect(() => {
  console.log('컴포넌트가 리렌더링 될 때마다 실행된다.');
});

의존값이 들어갈 배열 자체를 생략하면 해당 컴포넌트 혹은 부모 컴포넌트가 재평가 될 때마다 재실행된다.

clean up 함수

claen up 함수란?

useEffect 훅은 return 값으로 함수를 반환한다.
이 반환되는 함수를 clean up 함수라고 한다.
이 clean up 함수는 useEffect의 파라미터로 받은 함수가 실행될 때 바로 실행되지 않는다.
처음 useEffect 함수를 실행하고 나서, 이후 의존값이 바뀌어 다시 실행하기 전 그 사이에 clean up 함수가 실행된다. 또 uesEffect를 포함하고 있는 컴포넌트가 DOM에서 마운트 해제될 때마다 실행된다. 이 말은 즉슨 컴포넌트가 재사용될 때마다 실행된다.

clean up 함수가 실행되는 조건

  • 모든 새로운 사이드 이팩트 함수가 실행되기 전
  • 컴포넌트가 제거되기 전
  • 예외) 처음 사이드 이펙트 함수가 실행되기 전에는 실행되지 않는다.

활용 : 디바운싱

이메일과 패스워드의 입력을 모두 받은 후 즉 사용자가 타이핑을 중지하면 그 완성된 입력값을 체크하는 기술을 디바운싱이라고 한다.

이 디바운싱 기술을 useEffect의 반환값인 clean up 함수를 통해 구현할 수 있다.

clean up 적용 전

다음은 이메일과 패스워드의 입력을 받고 1초 후에 입력값을 체크하기 위해 작성한 코드이다.

useEffect(() => {
    setTimeout(() => {
      console.log('입력값 체크!');
    }, 1000);
  
  }, [email, password]);

setTimeout으로 email과 password의 입력을 받은 시점으로부터 1초 후에 파라미터로 받은 이펙트 함수를 실행하도록 했다.
하지만 이때 email과 password의 입력이 1초 이내로 여러번 들어오게 되면 들어온 만큼의 타이머가 쌓이게 된다. 이는 성능 저하로 이어질 수 있다.

clean up 적용 후

다음은 위의 문제를 clean up 함수로 해결한 코드이다.

useEffect(() => {
  const identifier = setTimeout(() => {
    console.log('입력값 체크!');
  }, 1000);
  
  return () => {
    console.log('이전 timeout 삭제');
    clearTimeout(identifier);
  };
}, [email, password]);

처음 사이드 이펙트 함수가 실행된 이후, email과 password 값이 바뀌고 다시 사이드 이펙트 함수가 실행되기 직전에 clean up 함수로 사이드 이펙트 함수의 타이머를 지워준다.
이렇게 하면 여러번 타이핑 값이 들어와도 마지막에 딱 한번만 입력값을 체크할 수 있게 된다.

profile
공부하고 내 것으로 만들자.

0개의 댓글