본문 바로가기

Libraries/React

[React] useEffect

728x90

 

   목차 

1. React 컴포넌트의 생애주기

2. React Hooks

3. useEffect

4. useEffect 사용법 예시

 

 

 

React의 Hook 중의 하나인 useEffect에 대해서 알아보자!

 

 


 

 

 

 React 컴포넌트의 생애주기 

 

React 컴포넌트의 생애주기는 3가지로 나뉜다.

처음 화면에 나타날 때를 Mount,

화면이 바뀌면서 리렌더링 되는 것을 Update,

화면에서 사라지는 것을 UnMount

이 3가지 단계로 진행된다.

 

 

 

 


 

 

 React Hooks 

 

 

리액트는 생애주기마다 실행할 수 있는 메서드를 가지고 있고, 이 메서드는 클래스형 컴포넌트에서밖에 사용하지 못한다.

그런데, 클래스형 컴포넌트는 사용할 때 코드의 길이가 길어지는 등 다양한 문제점이 있어서, 요즘에는 함수형 컴포넌트를 사용하는 추세이다.

그렇다면 이 메서드들을 '함수형 컴포넌트'에서 쓸 수 있는 방법은 없을까?

이것을 가능하게 하기위해 나온것이 리액트 Hooks이다.

원래 클래스형 컴포넌트가 근본적으로 가지고 있는 기능을 함수형 컴포넌트가 낚아채서(Hooking) 사용할수 있는 기능을 React Hooks라고 부른다.

 use 키워드를 앞에 붙여서 사용하는 것이 특징이다.

 

 

 

 


 

 

 useEffect 

 

 

useEffect는 2개의 파라미터를 전달하게 되는데,

첫번째 파라미터콜백함수를 전달하고,

두번째 파라미터의존성 배열(Dependency Array)을 전달한다. 

두번째 파라미터에 있는 값이 변화하면, 첫번째 파라미터인 콜백함수가 실행된다.

 

 


 

 

useEffect 사용법 예시

 

 1. 컴포넌트가 mount (생성)되는 순간 제어하기 

 

 Lifecycle.js 

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

const Lifecycle = () => {

  const [count, setCount] = useState(0); // 카운터에 사용됨
  const [text, setText] =  useState(""); // 인풋에 사용됨


  return <div style={{ padding: 20 }}>
    <div>
      {count}
      <button onClick={()=>setCount(count+1)}>+</button> // 카운터 버튼 생성
    </div>
    <div>
      <input value={text} onChange={(e) => setText(e.target.value)} /> // 인풋 생성
    </div>
  </div>;
};

export default Lifecycle;

 

 

useEffect 사용해보기

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

const Lifecycle = () => {

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

 useEffect(()=>{
 console.log("Mount!"); // 컴포넌트가 mount되는 시점에 콘솔에 한번 찍힘 
 },[])

  return <div style={{ padding: 20 }}>
    <div>
      {count}
      <button onClick={()=>setCount(count+1)}>+</button>
    </div>
    <div>
      <input value={text} onChange={(e) => setText(e.target.value)} />
    </div>
  </div>;
};

export default Lifecycle;

 

컴포넌트가 mount 되는 시점에 콘솔에 한 번 찍힌다.

카운터 버튼(+)을 눌러보면 컴포넌트가 업데이트가 되는데,

Dependency array를 빈배열로 전달하게 되면 콜백함수는 컴포넌트가 마운트되는 시점에만 작동하기 때문에

콘솔에 "Mount!"가 출력되지않음

따라서 컴포넌트가 마운트되는 시점에만 무언가를 하고 싶다면, useEffect의 두번째 인자인 Dependency array에 빈 배열을 전달해준 다음에, 콜백함수에 하고 싶은 일을 넣어주면됨.

 

 

 

 2. 컴포넌트가 업데이트 되는 순간 제어하기 

 

< 컴포넌트가 업데이트 되는 순간 >

(1) state가 변경될 때
(2) 부모에게서 내려받는 props가 바뀔 때
(3) 부모 컴포넌트가 리렌더링 될 때 
등등...

 

 Lifecycle.js 

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

const Lifecycle = () => {

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

 useEffect(()=>{
 console.log("Mount!"); 
 },[])
 
 useEffect(()=>{
  console.log("Update!");  // 업데이트 되는 순간 콘솔에 찍힘
  })

  return <div style={{ padding: 20 }}>
    <div>
      {count}
      <button onClick={()=>setCount(count+1)}>+</button>
    </div>
    <div>
      <input value={text} onChange={(e) => setText(e.target.value)} />
    </div>
  </div>;
};

export default Lifecycle;

 

useEffect의 두번째 인자인 Dependency array를 쓰지 않으면 콜백함수는 컴포넌트가 업데이트 되는 시점에 콘솔에 "Update!"가 출력됨.

카운터 버튼을 누르거나 인풋에 글을 작성하면 업데이트가 돼서 콘솔에 "Update!" 가 출력된다.

따라서 컴포넌트가 업데이트되는 순간에 무언가를 하고 싶다면,  두번째 인자를 생략하고 콜백함수에 하고싶은 일을 넣어주면 됨.

 

 

 

 

 

 3. Dependency array에 있는 값이 변하게 되면 그 순간 콜백함수가 수행이 된다. 

 

콜백함수는 [count] state가 변하는 순간 다시 호출이 된다.

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

const Lifecycle = () => {

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

 useEffect(()=>{
 console.log("Mount!"); 
 },[])
 
 useEffect(()=>{
  console.log("Update!"); 
  })

  useEffect(()=>{
    console.log(`count is update : ${count}`); 
  },[count]); // 콜백함수는 count state가 변하는 순간 다시 호출이 된다.

  useEffect(()=>{
    console.log(`count is update : ${count}`);
  },[text]); // 콜백함수는 text state가 변하는 순간 다시 호출이 된다.

  return <div style={{ padding: 20 }}>
    <div>
      {count}
      <button onClick={()=>setCount(count+1)}>+</button>
    </div>
    <div>
      <input value={text} onChange={(e) => setText(e.target.value)} />
    </div>
  </div>;
};

export default Lifecycle;

 

 

 

* 예제) 카운터가 5가 넘으면 1로 변경시키기

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

const Lifecycle = () => {

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

 useEffect(()=>{
 console.log("Mount!"); 
 },[])
 
 useEffect(()=>{
  console.log("Update!"); 
  })


// 예제 부분
  useEffect(()=>{ 
    console.log(`count is update : ${count}`); 
    if (count> 5 ){
      alert("count가 5를 넘었습니다. 따라서 1로 초기화합니다.");
      setCount(1)
    }
  },[count]);

  useEffect(()=>{
    console.log(`text is update : ${text}`);
  },[text]); 

  return <div style={{ padding: 20 }}>
    <div>
      {count}
      <button onClick={()=>setCount(count+1)}>+</button>
    </div>
    <div>
      <input value={text} onChange={(e) => setText(e.target.value)} />
    </div>
  </div>;
};

export default Lifecycle;

확인 버튼을 누르면 1로 돌아감

 

 

 

 4. 컴포넌트가 unmount (화면에서 사라지는) 되는 순간 제어하기 

 

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

const Lifecycle = () => {
  const [isVisible, setIsVisible] = useState(false);
  const toggle = () => setIsVisible(!isVisible);

  return (
    <div style={{ padding: 20 }}>
      <button onClick={toggle}>ON/OFF</button>
    </div>
  );
};

export default Lifecycle;

 

 

자식 컴포넌트 생성하기

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

const UnmountTest = () => {
  return <div>Unmount Testing Component</div>
}


const Lifecycle = () => {
  const [isVisible, setIsVisible] = useState(false);
  const toggle = () => setIsVisible(!isVisible);

  return (
    <div style={{ padding: 20 }}>
      <button onClick={toggle}>ON/OFF</button>
      {isVisible && <UnmountTest/>}
    </div>
  );
};

export default Lifecycle;

 

isVisible이 true일때만 UnmountTest가 화면에 렌더링 되게 하기

isVisible 값이 true면 <UnmountTest/>컴포넌트가 반환이 돼서 화면에 렌더링 됨

isVisible 값이 false면 <UnmountTest/>이 렌더링이 안됨

 

 

 

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

const UnmountTest = () => {

  useEffect(()=>{
  console.log("Mount!"); // Mount 시점에 실행이 됨
  
  return ()=>{
    console.log("Unmount!");  // Unmount 시점에 실행이 됨 
  }
  },[])


  return <div>Unmount Testing Component</div>
}


const Lifecycle = () => {
  const [isVisible, setIsVisible] = useState(false);
  const toggle = () => setIsVisible(!isVisible);

  return (
    <div style={{ padding: 20 }}>
      <button onClick={toggle}>ON/OFF</button>
      {isVisible && <UnmountTest/>}
    </div>
  );
};

export default Lifecycle;

 

 

728x90