React: useEffect()

HaByungNo·2022년 10월 15일
0

Today I Learned

목록 보기
13/16
post-thumbnail

useEffect()

어떠한 컴포넌트 있다고 하자

  • Mount(첫 랜더링) 되었을 때
  • Update(리랜더링) 되었을 때
  • Unmount(화면에서 사라짐) 되었을 때

위의 세 경우 특정한 작업을 수행 할 코드를 짜려면 useEffect() 를 사용한다.
인자로 콜백함수를 받으며, 형태는 아래와 같다.

  useEffect(() => {
    // 여기에 수행할 코드
  }, [의존성배열])

의존성 배열은 기준이 되는 해당 값을 하나 넣고 그 값이 변경될때 콜백 함수내 코드가 실행되도록 한다. 의존성배열로 빈배열[] 을 넣는다면 첫 랜더링시 딱 한번만 실행되고 이후로는 실행되지 않는다.

의존성배열을 쓰지 않는 경우엔 컴포넌트가 Mount, Update가 이루어 질 때마다 계속 콜백함수 내 코드가 실행된다.

UseEffect()의 CleanUp

UseEffect() 사용하면 정리 작업도 해줘야 할 때가 있다.
예를 들어 타이머를 동작했다가 멈춰야 하거나, 이벤트리스너를 등록했다가 이제는 제거해야한다던가 하는 경우가 있을 수 있겠다. 그럴 땐 UseEffect() 안 콜백함수에 return 값으로 함수를 주면 된다. 그 return 되는 함수에 원하는 정리 작업을 작성하면 된다.

형태는 아래와 같다.

useEffect(()=>{
  // 구독...
  
  return () => {
    // 구독 해지...
  }
  
)

이렇게 함수를 return 하면, 컴포넌트가 UnMount 될때, 또는 다음 랜더링 시 불려질 useEffect()가 실행되기 이전에 return 안 함수가 실행 된다.

useEffect()의 실행순서?

아래와 같은 React 코드가 있다.
어떤 순서대로 실행될까?

function App() {
  useEffect(() => {
    console.log(1);
  }, []);

  return ...
}

const OuterBox: FC = () => {
  useEffect(() => {
    console.log(2);
  }, []);

  return ...
};

const InnerBox: FC = () => {
  useEffect(() => {
    console.log(3);
  }, []);

  return ...
};

useEffect()는 컴포넌트가 렌더링이 된 후에 실행된다. 따라서 App이 render 되기 위해서는 OuterBox가 먼저 렌더링이 되어야 되고, OuterBox가 완전히 렌더링 되기 위해서는 InnerBox가 렌더링이 되어야 한다. 결론은 최하위에 있는 컴포넌트의 useEffect가 먼저 실행된다.


// 내가 짠 예제 코드
// 간단한 시계 Clock.jsx 컴포넌트를 만들고 
// App.js에서 토글식으로 조건부 랜더링 되게 했다.


// ./App.js
import React, { useState } from "react";

function App() {
  const [showClock, setShowClock] = useState(false);

  return (
    <div>
		<button onClick={()=>setShowClock(!showClock)}>시계!!!!!</button>
		{showClock && <Clock/>}
    </div>
        )
}
      </LikeConsumer>
    </LikeProvider>
  );
}

export default App;

Clock.jsx 컴포넌트에서는 useEffect() 안에 setInterval을 활용하여
Date() 객체에서 가져온 값을 1초마다 바꿔주도록 했다.

// ./components/Clock.jsx

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

const Clock = () => {
  
  const initialstate = String(new Date()).split("GMT")[0]
  const [time, setTime] = useState(initialstate);
  
  useEffect(() => {
    const myClock = setInterval(() => {
      let value = String(new Date()).split("GMT")[0]
      setTime(value);
      console.log(value)
    }, 1000);

    return ( () => {
      clearInterval(myClock)
      console.log("시계멈춤!!")
    }
      
    )
  }, []);

  return (
    <div
      style={{
        width: "200px",
        height: "100px",
        border: "2px solid green",
        margin: "10px 0",
        display: "flex",
        justifyContent: "center",
        alignItems: "center",
        flexDirection: "column",
      }}
    >
      <span>{time}</span>
    </div>
  );
};

export default Clock;
profile
프라고

0개의 댓글