ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 컴포넌트(4) 리액트 훅(react hook)사용 - useEffect
    React 리액트 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

    반응형

    댓글

Designed by Tistory.