React 리액트

컴포넌트(4) 리액트 훅(react hook)사용 - useEffect

dev.mk 2023. 9. 6. 15:27
반응형

useEffect란?

- 컴포넌트가 렌더링 될 때 특정 작업을 실행할 수 있도록 하는 Hook이다.

- useEffect 이후에(마운트 해제되는 때) clean-up (정리)를 실행할 수 있다.

 

기본형태

// 첫 번째 인자로는 effect 함수, 두 번째 인자로는 dependency array 
useEffect(() => {
    console.log('useEffect가 실행되면서 렌더링.')
	
    // effect 이후에 어떻게 정리(clean-up)할 것인지 표시
    return () => {
       ....
       // useEffect 종료되면 실행.
    }
}, []) // 빈 배열을 입력하는 경우 렌더링 될 때 마다 실행

 

App.js

import Main from './component/Main';
import './App.css';

function App() {
      return (
          <div className="App">
              <Main/>
          </div>
      );
}

export default App;

 

예제 1. componentDidMount() & componentDidUpdate() 를 표한하기

useEffect(() => {
	// 수행할 함수
});

src/component/Main.js

import React, { useState, useEffect } from "react";
const Main = () => {
    const [count, setCount] = useState(0);
    const countUp = () => setCount(count + 1);
    useEffect(() => {
        console.log("useEffect => ", count);
    });
    return (
        <div>
            <p>{count}번 클릭!</p>
            <button onClick={countUp}>클릭하기</button>
        </div>
    );
};
export default Main;

#결과

렌더링이 되고, count 스테이트가 변경될 때 마다 console.log가 찍힌다.

 

 

예제 2. jquery의 $( document ).ready(function() { } 와 유사한 표현

useEffect(() => {
	// 수행할 함수
}, 빈배열)

src/component/Main2.js

import React, { useState, useEffect } from "react";
const Main2 = () => {
    const [count, setCount] = useState(0);
    const countUp = () => setCount(count + 1);
    useEffect(() => {
        console.log("useEffect => ", count);
    },[]);
    return (
        <div>
            <p>{count}번 클릭!</p>
            <button onClick={countUp}>클릭하기</button>
        </div>
    );
};
export default Main2;

#결과

위의 예시와는 다르게, 최초 렌더링 시에만 console.log가 출력된다.

 

 

예제3. 특정값이 변경될때만 실행

useEffect(() => {
	// 수행할 함수
}, 특정배열);

src/component/Main3.js

import React, { useState, useEffect } from "react";
const Main3 = () => {
    const [count, setCount] = useState(0);
    const countClick = () => setCount(count + 1);
    useEffect(() => {
        console.log("useEffect print count => ", count);
    }, [count]);
  
    return (
        <div>
            <p>{count}번 클릭!</p>
            <button onClick={countClick}>클릭하기</button>
        </div>
    );
};
export default Main3;

 

#결과

useEffect 함수 배열 인자에 count를 넣고 count의 값이 변경되면 log가 출력된다.

 

 

예제 4. 배열인자에 여러 state 넣고 출력해보기

src/component/Main4.js

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

const Main3 = () => {
    
    const [count, setCount] = useState(0);
    const [name, setName] = useState("Dev.MK");
    const countClick = () => setCount(count + 1);
    const handleChangeName = (e) => setName(e.target.value);
  
    useEffect(() => {
        console.log("useEffect print count => ", count);
        console.log("useEffect print name => ", name);
    }, [name,count]);
  
    return (
        <div>
            <p>안녕하세요. {name} 입니다.</p>
            <input onChange={handleChangeName} />
            <p>{count}번 클릭!</p>
            <button onClick={countClick}>클릭하기</button>
        </div>
    );
};

export default Main3;

#결과

name값과 count값이 실시간으로 변경될 때 마다 log가 출력된다.

 

 

cleanup 함수란?
 - useEffect 안에서 return 할 때 실행 된다.(useEffcet의 뒷정리를 한다.)
 - 만약 컴포넌트가 마운트 될 때 이벤트 리스너를 통해 이벤트를 추가하였다면 컴포넌트가 언마운트 될 때 이벤트를 삭제 해주어야 한다. 그렇지 않으면 컴포넌트가 리렌더링 될 때마다 새로운 이벤트 리스너가 핸들러에 바인딩 될 것이다. 이는 자주 리렌더링 될 경우 메모리 누수가 발생할 수 있다.

// 첫 번째 인자로는 effect 함수, 두 번째 인자로는 dependency array 
useEffect(() => {
    console.log('useEffect가 실행되면서 렌더링.')
	
    // effect 이후에 어떻게 정리(clean-up)할 것인지 표시
    return () => {
       ....
       // useEffect 종료되면 실행.
    }
}, []) // 빈 배열을 입력하는 경우 렌더링 될 때 마다 실행

예제 5. clean-up 영역에 log 출력하기

src/component/Main4.js

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

const Main4 = () => {
    const [count, setCount] = useState(0);
    const countClick = () => setCount(count + 1);
    useEffect(() => {
        console.log("useEffect print count => ", count);
        return () => {
            console.log("useEffect cleanup count => ", count);
        }
    }, [count]);
    return (
        <div>
            <p>{count}번 클릭!</p>
            <button onClick={countClick}>클릭하기</button>
        </div>
    );
};

export default Main4;

#결과

- 클릭시 cleanup 함수에서는 이전 count값, 그리고 렌더링 후 변경된 count값이 출력
- useEffect가 실행되기 전 return 함수(clean-up)를 먼저 실행한다.
- componentWillUnmount() 역할을 할 수 있다.

 

 

예제 6. 타이머프로그램 만들기

src/component/Timer.js

 

import React, { useEffect }from 'react';

const Timer = (props) => {
    useEffect(() => {
        const timer = setInterval(() => {
            console.log('타이머 진행중....');
        }, 1000);
        
        // clean-up
        return () => {
            clearInterval(timer);
        }
    }, [])
    return(
        <div>
            <span>타이머 시작.</span>
        </div>
    )
}

export default Timer;

App.js

import { useState } from 'react'

import Timer from './component/Timer';
import './App.css';

function App() {
  const [showTimer, setShowTimer] = useState(false);
      return (
          <div className="App">
              <header className="App-header">
                  {showTimer && <Timer/>}
                  <button onClick={() => setShowTimer(!showTimer)}>토글 타이머</button>
              </header>
          </div>
      );
}
export default App;

# 결과 - 타이머 시작

log가 1초마다 출력된다.

 

# 결과 - 타이머 종료

다시 버튼을 누르면 타이머가 종료되는 것을 볼 수 있다.

clean-up 리턴안에 clearInterval를 함수하여 타이머를 초기화 시킨것을 볼 수 있다.

 

 

 

 

 

출처

https://goddaehee.tistory.com/308

https://itprogramming119.tistory.com/entry/React-useEffect-%EC%82%AC%EC%9A%A9%EB%B2%95-%EB%B0%8F-%EC%98%88%EC%A0%9C

반응형