[리액트] Hooks - useEffect

2023. 4. 25. 10:38개발/React

useEffect 란

  • 컴포넌트의 라이프사이클에 따라 Mount(랜더링), Update(리랜더링), Unmount(화면에서 사라짐)에 따라서 특정 로직을 수행하고 싶을 때 사용한다.
  • 인자로 콜백함수와, 의존성배열(dependency Array)을 받는다.
  • 의존성 배열에 값을 어떻게 넣어주는가에 따라 특정 라이플 사이클에만 동작하도록 실행조건을 제어 할 수있다(마운트 될때만, 특정값이 변경될 때만…)
  • 인자 내 콜백함수의 return 작성을 통해 수행한 동작에 대한 클린이 가능하다.
/* 콜백 함수만 받는 형태 */
useEffect(()=>{
 /* 로직 */
})

/* 콜백함수와 의존성 배열을 받는 형태*/
useEffect(()=>{

},[/* 빈 배열, 혹은 상태값이 담긴 배열*/])

React 에서 useEffect 사용하기

import 하기

import React, { useState, useEffect } from 'react'
// 시작은 import 부터 해주어야 합니다.

기본 사용방법

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

function HookPractice2() {
    const [level, setLevel] = useState(0)
    // 랜더링이 될때마다 호출됨.
    useEffect(()=>{
     console.log("랜더링 되었다!")   
    })

    // useStage를 사용하는 두가지 방법
    const oneTimelevelUp = () => {
        setLevel(level+1)
    }
    const mamyTimeslevelUp = () => {
        setLevel((level) => level + 1);
        setLevel((level) => level + 1);
        setLevel((level) => level + 1);
    }

    return (
        <div>
            <p>나의 레벨은? {level}</p>
            <button onClick={oneTimelevelUp}>레벨업</button>
            <button onClick={mamyTimeslevelUp}>레벨파워업</button>
        </div>
    );
}

export default HookPractice2;

코드에서 사용할 state값을 useState로 선언합니다. 여기에선 level 값을 상태값으로 선언해 주었습니다.

버튼을 클릭할 경우 값을 변경해 줍니다. 함수형 업데이트를 사용한 예제도 함께 첨부했습니다.

반면, 함수를 사용해서 호출한 경우 3번을 동시에 명령을 내리면, 그 명령을 모아 순차적으로 각각 1번씩 실행시킵니다.

최초 랜더링인 컴포넌트가 Mount 되었을때, 버튼 클릭을 통해 state가 변경되어 재 랜더링 되었을 때 동작하는 모습을 확인 할 수 있습니다.


기본 사용방법


활용하기 1 - 특정 상태가 변경 되었을 때 동작 ( 의존성 배열)

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

function HookPractice2() {
    const [level, setLevel] = useState(0)
    const [exp, setExp] = useState(0)

    // 경험치 값이 변경되어 랜더링 될때만 호출된다.
    useEffect(() => {
        console.log("랜더링 되었다~")
    },[**exp**])

    const levelUp = () => {
        setLevel(level + 1)
    }

    const expUp = () => {
        setExp(exp + 1)
    }

    return (
        <div>
            <p>나의 레벨은? {level}</p>
            <p>나의 경험치는? {exp}</p>
            <button onClick={expUp}>경험치업</button>
            <button onClick={levelUp}>레벨업</button>
        </div>
    );
}

export default HookPractice2;

최초로 마운트 되었을때, 경험치 값이 변경 되었을때만 useEffects 내 로직이 동작한다.


특정 상태가 변경 되었을 때 동작 ( 의존성 배열)


활용하기 2 - 마운트 되었을 때 동작 ( 의존성 배열)

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

function HookPractice2() {
    const [level, setLevel] = useState(0)
    const [exp, setExp] = useState(0)

    // 컴포넌트가 최초 랜더링 = 마운팅 되었을때만 동작한다.
    useEffect(() => {
        console.log("랜더링 되었다~")
    },[])

    const levelUp = () => {
        setLevel(level + 1)
    }

    const expUp = () => {
        setExp(exp + 1)
    }

    return (
        <div>
            <p>나의 레벨은? {level}</p>
            <p>나의 경험치는? {exp}</p>
            <button onClick={expUp}>경험치업</button>
            <button onClick={levelUp}>레벨업</button>
        </div>
    );
}

export default HookPractice2;

의존성 배열의 값을 비우면 최초 컴포넌트가 마운팅 되었을때만 동작하게 된다.


마운트 되었을 때 동작 ( 의존성 배열)


활용하기 3 - 클린업

// Wrap.jsx
import React, {useState} from 'react';
import HookPractice3 from './HookPractice3';
/**
 * HookPractice3 컴포넌트를 포함하는 부모 컴포넌트 입니다.
 */
function Wrap() {
    // true 일때 컴포넌트를 마운트 한다.
    const [callComponent, setCallComponent] = useState(false)

    // 버튼 클릭 이벤트
    const onClickEventHandler = ()=>{
        setCallComponent(!callComponent)
    }
    return (
        <>
            {callComponent && <HookPractice3/>}
            <button onClick={onClickEventHandler}>가보자고!</button>
        </>
    );
}

export default Wrap;

Wrap.jsx 컴포넌트에서 HookPractice3.jsx컴포넌트를 상태값 callComponent가 트루일때만 마운팅하고있다.

버튼 클릭이벤트를 통해 callComponent값은 변경된다.


// HooksPractice3.jsx
import React, { useEffect } from 'react';

function HookPractice3() {

    useEffect(()=>{
        const getPassion = setInterval(()=>{
            console.log("당신의 열정 온도는 올라가고 있습니다!!!!")
        }, 1000)
    },[])

    return (
        <div>
            <span>당신은 열정을 가지고 있나요? 콘솔을 확인해주세요.</span>
        </div>
    );
}

export default HookPractice3;

setImterval을 통해 1초에 한번씩 콘솔로그가 찍히는 동작을 수행한다.

하지만 컴포넌트가 화면에서 사라져도 해당 함수는 계속해서 진행된다. 이럴때 필요한 것이 클린업!


열정 머신!



useEffects내의 리턴문을 추가하고 그 리턴문안에 함수를 넣어준다.

리턴문 내 함수에서 클린작업을 하면 된다. 인터벌 함수를 클린하는 cleanInterval을 사용할것이다.

혹시 이벤트를 addLisner를 통해 붙어 주었다면 컴포넌트가 사라질때 이곳에서 remove리스너를 해주면 된다!

// HooksPractice3.jsx
import React, { useEffect } from 'react';

function HookPractice3() {

    useEffect(()=>{
        const getPassion = setInterval(()=>{
            console.log("당신의 열정 온도는 올라가고 있습니다!!!!")
        }, 1000)

                return () => {
            clearInterval(getPassion)
            console.log("잘하셨어요! 잠시 쉬는것도 열정을 충전하는 방법입니다!")
        }
    },[])

    return (
        <div>
            <span>당신은 열정을 가지고 있나요? 콘솔을 확인해주세요.</span>
        </div>
    );
}

export default HookPractice3;

의도한대로 컴포넌트가 언마운트 되면서 마운트될때 실행되었던 함수가 함께 종료됨을 확인할 수 있다.

클린업