[ReactNative] React Hooks - useEffect

bi_sz·2023년 9월 26일
0

ReactNative

목록 보기
8/37
post-thumbnail
post-custom-banner

모든 컴포넌트는 여러 종류의 lifeCycle 메소드를 가집니다.

클래스 컴포넌트의 생명주기

하나의 컴포넌트가 생성되고 업데이트되고, 제거되기까지의 과정입니다.

constructor

컴포넌트가 생성될 때 실행

reder

컴포넌트를 랜더링하는 메소드

componentDidMount

첫 랜더링을 마친 후에 딱 한 번 실행

componentDidUpdate

props 이나 state가 바뀌여서 리랜더링을 마쳤을 때 실행

componentWillUnmount

컴포넌트가 소멸되기 직전에 제거되기 직전에 호출되는 함수

componentDidMount 에서 등록한 이벤트가 있다면 componentWillUnmount에서 꼭 제거작업을 해주어야합니다.


https://velog.io/@bi-sz/ReactNative-ReactHooks
이전 게시글에서 useState를 학습하면서 사용했던 react-hook 프로젝트를 그대로 사용하겠습니다.

클래스형 컴포넌트

UseEffectWithClassComponent.js 파일을 추가해주었습니다.

constructor, render, componentDidMount, componentDidUpdate, componentWillUnmount 총 다섯가지의 생명주기가 구현되어있습니다.

App.js 에도 UseEffectWithClassComponent 를 import 해주고 실행하여 로그를 살펴보도록 하겠습니다.

생성

constructor -> render -> didMount 순으로 메소드가 실행되어 로그가 찍히는 것을 확인할 수 있습니다.

업데이트

state가 업데이트 되는 시점에서도 확인해보겠습니다.

버튼을 클릭하였고 render 부터 시작이 된 모습을 볼 수 있습니다.

prevProps {}, prevState {"count": 0} 부분은 DidUpdate 에서 두번 콘솔을 찍어주었기 때문에 로그에 나타납니다.

prevProps 는 바뀐 부분이 없고 ,넘어 오는 값도 없어 빈 오브젝트이고,
prevStatestate에 작성한 count 의 바뀌기 전 상태를 나타낸 것입니다.

버튼을 계속 클릭해주면 render -> DidMount가 반복적으로 로그에 찍히는 모습을 확인할 수 있습니다.

제거

컴포넌트가 랜더링이 되었다가 없어지는 순간이 있어야하는데,
그 순간을 state로 구현해주었습니다.

isTrue 라는 state를 만들어주고 boolean 값으로 설정해주었습니다.

isTrue 의 값이 ture 일 때는 랜더링을 해주고, 아닐 때에는 랜더링해주지 않는 코드로 수정해주었습니다.

isTruetrue값이니까 UseEffectWithClassComponent가 랜더링이 됩니다.
isTrueflase로 바뀌는 순간 null이 되어 WillUnmount로 넘어가는 것을 확인할 수 있습니다.

isTrue값을 flase로 바꿔줄 버튼을 추가해주었습니다.

UseEffectWithClassComponent 컴포넌트가 랜더링이되어있는 상태에서
toggle을 누르는 순간 false 가 되면서 UnMount가 되는것을 확인할 수 있고, componentWillUnMount 메소드가 호출이되어 로그가 찍히는 것을 확인할 수 있습니다.


함수형 컴포넌트

저는 미리 작성을 해두어서 App.js에서 UseEffectWithFunctionalComponent 부분 주석을 해제하였습니다.


함수형 컴포넌트에서 사용되지 않는 것

constructor

함수형 컴포넌트에는 constructor의 역할을 하는 것이 없습니다.
굳이 따지자면 컴포넌트 내에서 구현을 할 수는 있는데

`console.log("constructor")'

props 이나 state가 업데이트 되었을 때 항상 실행되는 부분이여서 constructor라고할 수는 없습니다.

render

return 이라는 부분이 render 를 담당하고 있습니다.
return 안에서 콘솔을 찍을 수 있는 방법이 없습니다.

DidMount, DidUpdate, WillUmmount

함수형 컴포넌트에서는 DidMount, DidUpdate, WillUmmount 를 구현할 수 있습니다.
이 세 가지를 모두useEffect 이라는 react hooks 으로 대체할 수 있습니다.

useEffect 로 componentDidMount 대체

count, isOn, input, isRefresh state는 미리 작성해두었습니다.

import React, { useEffect, useState } from "react";

useEffect 를 react에서 import 해줍니다.

useEffect에서 두 번째 인자가 의존성 배열이며,
의존성 배열 안에 있는 값들이 바뀌었을 때 첫 번째 인자에 있는 함수를 호출합니다.

의존성 배열이 하나도 없기 때문에, 어떠한 값이 바뀌더라도 이 부분은 호출이 되지 않습니다.
랜더링 될 때 최초에 한 번만 실행되어 componentDidMount를 대체할 수 있습니다.

useEffect 로 componentDidUpdate 대체

count가 바뀔 때를 감지하는 useEffect를 작성해주었습니다.


DidMount와, DidMount 부분만 작성된 상태로 실행을 해 보았습니다.

DidMount는 첫 랜더링이기 때문에 출력이 되었고,

DidUpdatecount의 값이 변경이 될 때마다 이 함수가 호출됩니다.
첫 랜더링을 하면서 count의 초기값을 0으로 설정해준 것도 값이 변경되었다 인식을 하여 출력이 되었습니다.

버튼을 클릭하면 DidMount는 첫 실행 한 번만 보여지고,
DidUpdate는 첫 실행 후 count 가 0으로 초기화되면서 보여지고,
그 이후로는 버튼을 클릭하여 count 의 값이 변경될 때마다 로그가 나타나는 것을 볼 수 있습니다.

클래스 컴포넌트에서는 변경 이전 값이 출력되었는데
DidUpdate는 count가 Update될 때 호출되기 때문에,
함수형 컴포넌트에서는 변경 이후의 값이 출력됩니다.

스위치버튼인 isOn 부분도 작성하여 실행해보았습니다.

isOn부분을 업데이트 할때는 count 부분이 호출되지 않고,
count 부분을 호출할 때에는 isOn 부분을 호출하지 않습니다.

의존성 배열에 존재하는 useEffect 만 실행되는 것을 확인할 수 있습니다.

input 도 마찬가지로 다른 useEffect 함수가 호출되지 않고 의존성 인자를 가진 input 을 갖고잇는 useEffect 함수만 호출되어 로그가 찍히는 것을 확인할 수 있습니다.

useEffect 의 특성을 이용한 예시

ActivityIndicator

import { 
  View, Text, Button, TextInput, Switch, ActivityIndicator,
} from "react-native";

새로고침을 하는 경우 사용되는 ActivityIndicator 를 reactNative에서 import 해줍니다.

새로고침을 눌렀을 때, 데이터를 가져오는 중인 모습을 표시하는 UI 입니다.

새로고침을 누르고 2초동안 보여지도록 수정해보겠습니다.
isRefresh가 되는 동안만 ActivityIndicator를 보여주도록 수정하면 됩니다.

isRefresh state를 선언해 주었고, 초기값은 false 입니다.

isRefreshtrue 일 때만 ActivityIndicator 를 보이도록하고,
새로고침 버튼을 눌렀을 때 isRefresh값이 true가 되도록 작성해주었습니다.


보통은 refresh가 됐을때 데이터를 불러오는 로직으로 많이 사용됩니다.

위 사진과 같이 새로고침을 눌렀을 때 바로 api 를 호출해도 되지만,
useEffect를 사용하는 방법도 많이 사용됩니다.

새로고침을 누르면 isRefeashtrue로 만들어줍니다.
새로고침이 계속 되는 것이 아닌 데이터가 다 불러와 졌을 때는 다시 false로 바뀌어야합니다.

useEffect에서 isRefresh가 바뀌는것을 감지하고, isRefreshtrue 일 때만 값을 false로 변경해줍니다.

바뀌자마자 바로 false가 되면 로딩이 의미가 없기 때문에 setTimeout명령을 사용해서 특정 밀리세컨드 이후에 실행하도록 명령을 내려줍니다. 두 번째 인자에는 밀리세컨드를 작성해주면 됩니다.

새로고침 버튼을 누른 후 2초뒤에 사라지는 것을 확인할 수 있습니다.


어떠한 값이 변경되었을때, 그 변경을 인지하여 다른 동작을 해야될 때 useEffect가 사용됩니다.

profile
https://li-yo.tistory.com/ 티스토리 블로그 이전 하였습니다.
post-custom-banner

0개의 댓글