React - SideEffect & UseEffect

Seong Ho Kim·2023년 12월 25일

React

목록 보기
15/19

1. SideEffect

  • React 컴포넌트가 화면에 랜더링 된 이후로 비동기적으로 처리되어야 하는 부수적인 효과를 SideEffect 라고 한다.(즉, 함수가 함수 내부의 값 외에 외부의 값을 읽어오거나, 수정하는 행위를 의미하는 것이다.)
  • 뜻은 부작용 이라는 뜻을 가지고 있는데, 부수효과 의 느낌으로 주요한 효과에 따라서 발생하는 것을 말하는 것이다.

(1-1) 외부의 상태를 읽어오기

const num = 1;

const result = (x) => {
	return x + num; 
}
  • 여기서 num 이라는 변수에 1이 할당되어 있고 result 라는 함수엔 x를 인자로 받아와 x랑 num을 더한 값을 반환하고 있다. 여기서 result 함수 내부가 아닌 num 이라는 변수를 읽어오고 인자로 받아온 x랑, num을 더한 값을 반환하기 때문에 Side Effect가 동작됨을 알수 있다.

(1-2) 외부의 상태를 변형시키기

let num;

const result = (x) => {
	num = x + 1;
}
  • 여기서 num 이라는 외부 변수가 선언되어 있고, result 라는 함수가 있는데 result 함수는 x를 인자로 받아오고 있다. 여기서 result 함수는 인자로 받아온 x를 1을 더해 외부에 있는 num 변수에 적용시키려 하고있다. 이때, 값이 없는 num 변수에 값을 1씩 더해 할당시키려 했기 때문에 Side Effect가 동작됨을 알 수 있다.

2. 함수 컴포넌트의 Side Effect

  • 함수 컴포넌트에서의 Side Effect는 UI를 그려낼때 발생되는 과정에서의 side effect는 무궁무진하게 많겠지만 대표적인 사례는 다음과 같다.

(2-1) Data Fetching

  • 프론트엔드는 복잡한 UI를 구성하고 변화시키는 데에 초점을 두고 있기 때문에, 이러한 구조 속에서 프론트엔드가 백엔드 API를 통해서 기존에 저장된 데이터를 가져오는 행위는 필수적으로 발생하게 된다.

(2-2) DOM 접근 및 조작

  • React는 DOM의 조작을 React에서 대신해주고 개발자는 UI와 핵심 로직에만 신경 쓰도록 선언적인 개발을 가능하게 해주기 때문에 DOM에 직접 접근할 일이 많지 않지만, 특정 상황(document 객체에 scroll eventListener를 등록하는 등)에서는 DOM에 접근하고 직접 조작을 해야 하는 상황이 발생하기도 한다.

(2-3) 구독

  • 구독은, 어떤 것의 변화를 계속해서 지켜보고 변화가 발생하면 특정한 액션을 취하는것 을 말한다. 예를 들어 우리가 유튜브를 보면서 해당 컨텐츠를 구독을 함으로써 해당 유튜버의 변화를 계속해서 지켜보고 만약 새로운 영상이 올라오면 알림을 받거나, 메인 피드에 노출시키는 액션을 발생시키게 된다. 결론으론 Javascript 에서 일정 시간이 지나면 특정 동작을 수행해 주는 메서드인 setTimeout, 일정 시간마다 특정 동작을 수행해주는 setInterval 메서드를 제공해주고 이를 이용해서 시간의 변화에 따라 원하는 동작을 이행시킬 수 있다.

Side Effect 요약)

React 에서 Side Effect를 언제 발생시켜야 하는지에 대한 조건은?

  • 랜더링이 모두 마운팅 되고난 이후에 Side Effect를 실행해야 한다.
  • 내가 원할때만 조건부로 실행할 수 있어야 한다.

3. UseEffect

  • 컴포넌트가 랜더링 될때 특정 작업을 수행하는 행위를 말한다. (React 에서 useEffect 훅을 사용하면 함수 컴포넌트 내에서도 Side Effect를 사용할 수 있다.)

(3-1) UseEffect 사용 방법

useEffect(()=> {
	alert('이곳은 useEffect가 동작하는 곳입니다');
},[])
  • 참고로 useEffect는 콜백 함수를 가진 함수로 매개변수를 가진다.

(3-2) UseEffect 동작 방식

  • 렌더링 이후에는 무조건 useEffect에 전달된 콜백 함수를 호출하고 다음 렌더링부터는 아래의 조건에 따라 동작한다.

    1) 의존성 배열이 전달되지 않았다면, 매번 랜더링때마다 콜백 함수를 호출한다.
    2) 의존성 배열이 전달되었다면, 의존성 배열의 값을 검사한다.
    3) 의존성 배열에 있는 값 중 하나라도 이전 렌더링과 비교했을 때 달라졌다면 콜백 함수를 호출한다.
    4) 의존성 배열에 있는 값 중 하나라도 이전 렌더링과 비교했을 때 달라지지 않았다면 콜백 함수를 호출하지 않는다.

  • 결론적으로 useEffect의 첫번째 인자로 받는 콜백함수는 useEffect를 실행시킬 동작을 결정하고, 두번째 인자로 받는 의존성 배열은 실행시킬 타이밍을 결정짓는다.

(3-3) 조건부 없이 Side Effect(UseEffect) 동작 시키기

import React from 'react';

const App = () => {
	console.log('이곳은 useEffect가 동작하지 않는 곳입니다.'); // 1

	useEffect(() => {
    	console.log('이곳은 useEffect가 동작하는 곳입니다'); // 2
    })
    
    console.log('이곳은 콘솔이 출력된 이후에 JSX를 return 하여 랜더링 됩니다.') // 3
    return (
    	<h1>Hello Kim</h1>
    );
}

export default App;

1번 요약)

  • 해당 코드는 useEffect가 없기 때문에 App 함수 컴포넌트를 실행하게되면 바로 실행된다.

2번 요약)

  • 해당 코드는 return문의 text가 랜더링이 끝난 이후에 실행된다.

3번 요약)

  • 해당 코드는 콘솔이 출력된 이후로 JSX를 return 하여 h1 태그의 text를 랜더링 한다.

(3-4) 조건부로 Side Effect(UseEffect) 동작 시키기

useEffect(()=> {
	alert('이곳은 useEffect가 동작하는 곳입니다');
},[])

// () : 인자(매개변수)
// () => {} : 콜백함수
// [] : 의존성 배열
  • 여기서 의존성 배열이란? UseEffect의 두번째 조건을 가진 매개변수를 가진다. 의존성 배열이 바로 side effect의 발생 여부를 결정짓는다.
// 1
useEffect(() => {
	// sideEffect
})

// 2
useEffect(() => {
	// sideEffect
}, [value])

// 3
useEffect(() => {
	// sideEffect
}, [value1, value2])

1번 요약)

  • 의존성 배열이 전달되지 않았으므로 랜더링 이후로 매번 마다 sideEffect를 동작시킨다.

2번 요약)

  • 랜더링 이후로 sideEffect를 동작시킨뒤, value의 값을 검사하고 그 이후로 value 값이 변했을때만 sideEffect를 실행시킨다.

3번 요약)

  • 랜더링 이후로 sideEffect를 동작시킨뒤, value1, value2의 값을 검사하고 그 이후로 value1, value2 둘중에 하나라도 변했을때 sideEffect를 실행시킨다.

4. Rendering & Effect Cycle

  • 해당 사진은 useEffect와 React Component가 렌더링 되는 과정을 함께 도식화 한 다이어그램

(4-1) 요약
1. 컴포넌트가 실행될때 처음 마운트 되어 랜더링 시킨다.
(최초로 진행되는 렌더링은 브라우저에 처음으로 이 컴포넌트가 보였다는 의미를 가진것으로 이해하면 된다.)
2. useEffect 첫 번째 인자로 넘겨준 콜백 함수가 호출된다. (Side Effect)
3. 컴포넌트의 state 또는 props가 변경되었을 경우 리렌더링이 발생한다. (updated)
4. useEffect는 두 번째 인자에 들어있는 의존성 배열을 확인한다

  • A. 만약 의존성 배열이 전달되지 않았거나 / 의존성 배열 내부의 값 중 이전 렌더링과 비교했을 때 변경된 값이 하나라도 있다면 첫 번째 인자로 넘겨준 콜백 함수가 호출된다. (Side Effect)
  • B. 의존성 배열 내부의 값 중 이전 렌더링과 비교했을 때 변경된 값이 없다면 콜백 함수를 호출하지 않는다.
  • C. state 또는 props가 변경된다면 3~4의 과정을 반복한다.
profile
안녕하세요 Junior UIUX Designer 입니다 😊

0개의 댓글