[React] useEffect

-·2022년 11월 26일
0
post-custom-banner

useEffect

어떠한 컴포넌트가 Mount(화면에 첫 렌더링) / Update(특정 props가 바뀔때) / Unmount (화면에서 사라질 때) 되었을 때 특정 작업을 처리할 코드를 실행시켜주기 위해 useEffect를 사용한다.

📌 useEffect( ( ) => { } )
useEffect hook은 인자로 콜백함수를 받는다.
콜백 함수란 다른 함수의 인자로 전달된 함수를 의미한다.
이 콜백 함수 내부에 우리가 원하는 작업을 해줄 코드를 작성하여준다.

useEffect 함수는 두가지 형태가 있다.

  1. useEffect 의 인자로 하나의 콜백함수만 받는 형태
  • 렌더링 될 때마다 매번 콜백이 실행된다.
  • 즉, 컴포넌트가 맨 처음 화면에 렌더링 될때 & 컴포넌트가 다시 렌더링될 때 실행된다.
  1. useEffect의 첫 번째 인자로 콜백 함수, 두번째 인자로 배열을 받는 형태
  • 2 번에서 말하는 배열은 다른 이름으로 defendency array 라고 한다.
  • 매번 렌더링이 될 때마다 실행되는 것이 아니라 컴포넌트가 첫 렌더링 될 때 실행 & 배열 안에 들어있는 요소의 value가 바뀔때 실행이된다.
  • 만약 빈 배열을 전달해준다면 컴포넌트가 맨 처음 화면에 렌더링 될 때만 실행이 된다.

clean up 함수- 정리 작업을 처리

ex) 타이머라고 치면 더이상 타이머가 필요 없을 때 타이머를 멈추는 정리 작업
ex) 어떤 이벤트리스너를 등록을 했다면 컴포넌트가 언마운트 될 때 등록한 이벤트를 제거해주는 작업

이러한 정리 작업을 처리하려면 useEffect의 return 값으로 함수를 넣어준다.
그러면 해당 컴포넌트가 언마운트될 때 혹은 다음 렌더링 시 불릴 useEffect가 실행되기 이전에 그 함수가 실행이 된다.


예제 1

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

const SideEffect = () => {
 const [count, setCount] = useState(0);
 const [text, setText] = useState("");


 // count 값이 변했을 때만 이 콜백함수를 호출되고 text값이 변할 때는 useEffecdt의 콜백함수가 호출되지 않는다.
 useEffect(() => {
   console.log("count changed");
 }, [count]);

 
   // 반대로, text 값이 변했을 때만 이 콜백함수를 호출되지만 count값이 변할 때는  이 useEffect는 실행되지 않는다.
 useEffect(() => {
   console.log("text changed");
 }, [text]);

 // count와 text 둘 중 하나라도 변했다면, 이 useEffect는 실행된다.
 useEffect(() => {
   console.log("count & text when?");
 }, [count, text]); // 

 // 첫 번째 렌더링에서만 실행되고 두번째부터 마지막까지 절대 호출되지 않기를 원한다면, 의존생 배열에 [] 빈 배열을 넣는다.
 // 감지할 값이 없기때문에 첫번째 렌더링시에만 effect가 호출된다.
 useEffect(() => {
   console.log("only first render");
 }, []);

 useEffect(() => {
   console.log("------------------");
 });

 console.log("count", count);
 console.log("text", text);
 console.log("Render");

 return (
   <div>
     <div className="wrapper">
       <h1>Count : {count}</h1>
       <button onClick={() => setCount(count + 1)}>count up</button>
     </div>
     <input
       onChange={(e) => setText(e.target.value)}
       type="text"
       value={text}
     />
   </div>
 );
};

export default SideEffect;

예제 2


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

// 1. 컴포넌트를 count라는 state를 가지고 있고 useState를 통해 
// 버튼을 눌렀을 떄 state인 count가 올라가게끔 만들어준다.
// 2. useEffect 를 사용한다.

function UseEffect() {
  const [count, setCount] = useState(1);
  const [name, setName] = useState("");

  const handleCountUpdate = () => {
    setCount(count + 1);
  };
  const handleInputChange = (e) => {
    setName(e.target.value);
  };

  // 콘솔창이 언제 출력되는지 아래 코드를 실행시켜보자.
   
   // 렌더링마다 매번 실햄됨.
    useEffect(() => {
      console.log("렌더링 지옥!");
    });

    // 마운팅 + name이 변경될때만 실행.
    useEffect(() => {
      console.log("name 변화");
    }, [name]);

    // 마운팅 + count가 변화될때마다 실행.
    useEffect(() => {
      console.log("count 변화");
    }, [count]);

  // useEffect를 맨 처음 화면 렌더링될때만 부르고 싶다면? 
  // dependecy array를 빈 배열로 두번째 인자에 넣어두면된다.
  useEffect(() => {
    console.log("mounting!");
  }, []);

  return (
    <div>
      <div>
        <button onClick={handleCountUpdate}>Update</button>
        <span>count : {count}</span>
      </div>

      <div>
        <input type="text" value={name} onChange={handleInputChange} />
        <span>name: {name} </span>
      </div>
    </div>
  );
}

export default UseEffect;


예제 3. useEffect 를 사용해 타이머 만들기

component 폴더를 하나 생성하고 그 안에 Timer.js파일을 만든다.

//Timer.js

import React, { useEffect } from "react";

const Timer = (props) => {
  useEffect(() => {
    
    // setInterval : 정해진 주기마다 특정 로직을 반복해야할 때 사용하는 메서드.
    // 정리 작업을 해주는 코드가 없을 경우,
    // 타이머가 언마운트 되었을 때 1초마다 찍히는 콘솔창이 멈추지 않고 계속 작동될 것이다.
    // 정리 작업을 해주는 코드를 추가하여 타이머가 언마운트 되었을 때 timer가 종료되도록(멈추도록)해보자!
    // 정리를 하려면? useEffect의 return 값으로 함수를 넣어준다. 그리고 그 함수 안에서 정리작업을 처리해준다.

    const timer = setInterval(() => {
      console.log("타이머 돌아가는중...");
    }, 1000);
    return () => {
      clearInterval(timer);
      console.log("타이머가 종료되었습니다!");
    };
  }, []);

  return (
    <div>
      <span>타이머를 시작합니다. 콘솔을 보세요.</span>
    </div>
  );
};

export default Timer;

💡 App.js에 component 인 Timer import해야 화면에 렌더링되니 잊지말기!

//App.js//

import React, { useState, useEffect } from "react";
import Timer from "./component/Timer";

// Timer component를 계속 보여주는게 아니라 showTimer가 true일때만 타이머를 보여주고싶다.


function App() {
  const [showTimer, setShowTimer] = useState(false);

  return (
    <div>
      {/* 아래 코드가 쇼타이머가 true일때만 Timer를 보여주겠다는 코드  */}
      {showTimer && <Timer />}
      {/* 버튼이 클릭될 때 쇼타이머가 false->true 혹은 true -> false 로 바뀌게하는 코드 */}
      <button onClick={() => setShowTimer(!showTimer)}>Toggle Timer</button>
    </div>
  );
}

export default App;
post-custom-banner

0개의 댓글