โš™๏ธFrontend/REACT

[React] useEffect (๋ผ์ดํ”„์‚ฌ์ดํด, Dependency array)

soonybutter 2025. 5. 22. 16:35
728x90

 


 

 

๐Ÿ’กuseEffect๋ž€?

- React์—์„œ ์ปดํฌ๋„ŒํŠธ์˜ ๋ผ์ดํ”„์‚ฌ์ดํด์„ ๋‹ค๋ฃจ๊ธฐ ์œ„ํ•œ ๋Œ€ํ‘œ์ ์ธ Hook์ด๋‹ค.

- ์ƒ๋ช… ์ฃผ๊ธฐ ๋ณ„ ํŠน์ • ๋กœ์ง์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ค€๋‹ค.

- ์ „ํ†ต์ ์ธ ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ์—์„œ ์‚ฌ์šฉํ•˜๋˜ componentDidMount, componentDidUpdate, componentWillUnmount๋ฅผ ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ์—์„œ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” Hook์ž„

 

= ์ฃผ๊ธฐ๋ณ„ ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ(side effect)๋ฅผ ์ œ์–ดํ•œ๋‹ค.

 

 

 

* ๋ฆฌ์•กํŠธ ๋ผ์ดํ”„์‚ฌ์ดํด ( life-cycle )

: Mount(ํƒ„์ƒ)- Update(๋ณ€ํ™”)- Unmount(์ฃฝ์Œ) ์œผ๋กœ ๊ตฌ์„ฑ

 

 

์ฃผ๊ธฐ๋ณ„ sideEffect ์˜ˆ์‹œ

 


 

 

 

์•„๋ž˜์˜ ์˜ˆ์‹œ ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด useEffect๋ฅผ ์ •๋ฆฌํ•ด๋ณด์ž.

// App.jsx

import './App.css'
import Viewer from "./components/Viewer";
import Controller from "./components/Controller";
import Even from './components/Even';
import {useState, useEffect, useRef } from 'react';

function App() {

  const [count, setCount] = useState(0);
  const [input, setInput] = useState("");
  
  //false: ์•„์ง ์ด ์ปดํฌ๋„ŒํŠธ๋Š” ๋งˆ์šดํŠธ๋˜์ง€์•Š์•˜๋‹ค ์˜๋ฏธ
  const isMount =useRef(false);

  
  // 1. ๋งˆ์šดํŠธ: ํƒ„์ƒ (callbackํ•จ์ˆ˜ ๋งŒ๋“ค๊ณ , deps์—๋Š” ๋นˆ ๋ฐฐ์—ด ๋„ฃ์Œ)
  useEffect(()=>{
    console.log("mount");
  },[]);

  
  // 2. ์—…๋ฐ์ดํŠธ: ๋ณ€ํ™”, ๋ฆฌ๋ Œ๋”๋ง
  useEffect(()=>{
    if(!isMount.current){
      isMount.current= true;
      return;
    }
    console.log("update");
  });

  // 3. ์–ธ๋งˆ์šดํŠธ: ์ฃฝ์Œ

  useEffect(()=>{
    console.log(`count: ${count}`);
    console.log(`input:${input}`);
  },[count,input])

  const onClickButton = (value)=>{
    setCount(count + value);
  };
  
  return (
    <div className ="App">
    <h1>Simple Counter</h1>
    <section>
      <input value={input} onChange={(e)=>{
        setInput(e.target.value);
      }}/>
    </section>
    <section>
      <Viewer count={count}/>
      {count %2===0 ? <Even/> : null}
    </section>
    <section>
      <Controller onClickButton={onClickButton}/>
    </section>
    </div>
  );
}

export default App;

 

// Even.jsx

import {useEffect} from "react";

const Even =() =>{
    
    useEffect(()=>{

        // ํด๋ฆฐ์—…(์ •๋ฆฌํ•จ์ˆ˜)
        // mount ๋ ๋•Œ ์‹คํ–‰, amount๋ ๋•Œ ์ข…๋ฃŒ๋˜๋ฉด ์ •๋ฆฌํ•จ์ˆ˜ ํ˜ธ์ถœ๋จ!
        return () =>{
            console.log("unmount");
        };

    },[]);

    return <div>์ง์ˆ˜์ž…๋‹ˆ๋‹ค</div>;
};

export default Even;

 

 

 

 

 

โš™๏ธ๋งˆ์šดํŠธ ์‹œ์ :  ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ฒ˜์Œ ํ™”๋ฉด์— ๋‚˜ํƒ€๋‚  ๋•Œ

useEffect(() => {
  console.log("mount");
}, []);

 

์œ„ ์ฝ”๋“œ๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ฒ˜์Œ ๋งˆ์šดํŠธ๋  ๋•Œ ํ•œ ๋ฒˆ๋งŒ ์‹คํ–‰๋œ๋‹ค.

*dependency array๋ฅผ ๋นˆ ๋ฐฐ์—ด([])๋กœ ์ฃผ์—ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๋นˆ ๋ฐฐ์—ด์„ ์ฃผ๋ฉด, ํ•ด๋‹น useEffect๋Š” ์˜ค์ง ์ฒ˜์Œ ๋ Œ๋”๋ง๋  ๋•Œ๋งŒ ์‹คํ–‰๋œ๋‹ค.

์ฃผ๋กœ API ํ˜ธ์ถœ, ์ดˆ๊ธฐ ์„ธํŒ… ๋“ฑ์— ์‚ฌ์šฉ๋œ๋‹ค.

 

 

 

 

๐Ÿ’กDependency array๋ž€?

= (deps ,  ์˜์กด์„ฑ ๋ฐฐ์—ด)

- useEffect ์—์„œ ์–ธ์ œ effect ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋  ์ง€๋ฅผ ์ œ์–ดํ•˜๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.

์–ด๋–ค ์ƒํƒœ๋‚˜ props๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งŒ effect๊ฐ€ ์‹คํ–‰๋˜๊ฒŒ ํ•˜๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉํ•จ.

 

๐ŸŒŸ useEffect๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ชจ๋“  ๋ Œ๋”๋ง๋งˆ๋‹ค ์‹คํ–‰๋จ์œผ๋กœ,

์˜์กด์„ฑ ๋ฐฐ์—ด์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐฐ์—ด ์•ˆ์— ์žˆ๋Š” ๊ฐ’๋“ค์ด ๋ณ€๊ฒฝ๋  ๋•Œ๋งŒ useEffect๊ฐ€ ์‹คํ–‰๋˜๋„๋ก ์ œํ•œํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

 

 

 

 

โš™๏ธ์—…๋ฐ์ดํŠธ ์‹œ์  : 1. ํŠน์ • ๊ฐ’์ด ๋ฐ”๋€” ๋•Œ

useEffect(() => {
  console.log(`count: ${count}`);
  console.log(`input: ${input}`);
}, [count, input]);

 

์ด ์ฝ”๋“œ๋Š” count ๋˜๋Š” input ๊ฐ’์ด ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ์‹คํ–‰๋˜๊ณ  ์žˆ๋‹ค.

dependency array์— ๋“ค์–ด๊ฐ„ ๋ณ€์ˆ˜๋“ค์ด ๋ฐ”๋€Œ๋ฉด, ๊ทธ์— ๋”ฐ๋ผ ํ•ด๋‹น useEffect๋„ ๋‹ค์‹œ ์‹คํ–‰๋œ๋‹ค.

์ด๋ฅผ ํ†ตํ•ด ํŠน์ • ์ƒํƒœ(state)๊ฐ€ ๋ฐ”๋€Œ์—ˆ์„ ๋•Œ ๋กœ์ง์„ ๋ถ„๋ฆฌํ•˜์—ฌ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋ฌด๋ถ„๋ณ„ํ•œ ๋ฆฌ๋ Œ๋”๋ง์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด์ฒ˜๋Ÿผ useEffect๋Š” ์„ ํƒ์ ์œผ๋กœ ๋ฆฌ๋ Œ๋”๋ง ๋กœ์ง์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค€๋‹ค.

 

 

 

โš™๏ธ์—…๋ฐ์ดํŠธ ์‹œ์  : 2. ์กฐ๊ฑด์ถ”๊ฐ€

const isMount = useRef(false);

useEffect(() => {
  if (!isMount.current) {
    isMount.current = true;
    return;
  }
  console.log("update");
});

 

์œ„ ์ฝ”๋“œ๋Š” ๋ชจ๋“  ๋ Œ๋”๋ง๋งˆ๋‹ค ์‹คํ–‰๋˜์ง€๋งŒ, ์ฒ˜์Œ ๋งˆ์šดํŠธ ์‹œ์ ์—๋Š” ์‹คํ–‰์„ ๋ง‰๊ธฐ ์œ„ํ•ด useRef๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค.

isMount๋ผ๋Š” ref ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด์„œ ์ฒ˜์Œ์—” false๋กœ ์„ค์ •ํ•˜๊ณ , ๋งˆ์šดํŠธ ์ดํ›„๋ถ€ํ„ฐ๋งŒ console.log("update")๊ฐ€ ์ฐํžˆ๋„๋ก ์ฒ˜๋ฆฌํ•˜์˜€๋‹ค.

useRef hook์„ ํ™œ์šฉํ•ด์„œ ์ผ๋ฐ˜์ ์ธ ๋งˆ์šดํŠธ/์—…๋ฐ์ดํŠธ ๊ตฌ๋ถ„์ด ํ•„์š”ํ•œ ์ƒํ™ฉ์—์„œ ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

 

 

โš™๏ธ์–ธ๋งˆ์šดํŠธ ์‹œ์ : ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์‚ฌ๋ผ์งˆ ๋•Œ

useEffect(() => {
  return () => {
    console.log("unmount");
  };
}, []);

์ด ์ฝ”๋“œ๋Š” Even ์ปดํฌ๋„ŒํŠธ์—์„œ ์‚ฌ์šฉ๋˜์—ˆ์œผ๋ฉฐ, ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํ™”๋ฉด์—์„œ ์ œ๊ฑฐ๋  ๋•Œ ์ฝ˜์†”์— "unmount"๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.

useEffect์˜ return ๊ตฌ๋ฌธ์€ *ํด๋ฆฐ์—… ํ•จ์ˆ˜๋กœ์„œ, ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์‚ฌ๋ผ์งˆ ๋•Œ ์ •๋ฆฌ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ค€๋‹ค.

(์˜ˆ๋ฅผ ๋“ค์–ด, ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ ์ œ๊ฑฐ, ํƒ€์ด๋จธ ์ •๋ฆฌ, ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ ๋“ฑ์„ ์ด๋ ‡๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜์žˆ๋‹ค.)

 

 

 

 

๐Ÿ’กํด๋ฆฐ์—… ํ•จ์ˆ˜(clean-up function) ์ด๋ž€?

- ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์–ธ๋งˆ์šดํŠธ๋˜๊ฑฐ๋‚˜(= ํ™”๋ฉด์—์„œ ์‚ฌ๋ผ์ง€๊ฑฐ๋‚˜), effect๊ฐ€ ๋‹ค์‹œ ์‹คํ–‰๋˜๊ธฐ ์ง์ „์— ์ˆ˜ํ–‰๋˜๋Š” ์ •๋ฆฌ ์ž‘์—…

→ ๋ถˆํ•„์š”ํ•œ ๋™์ž‘ ์ค‘๋‹จ์„ ์œ„ํ•ด ์‚ฌ์šฉ

useEffect(() => {
  // effect ์‹คํ–‰ ๋กœ์ง
  console.log("Effect ์‹คํ–‰");

  return () => {
    // ํด๋ฆฐ์—… ํ•จ์ˆ˜
    console.log("Effect ์ •๋ฆฌ");
  };
}, [์˜์กด์„ฑ ๋ฐฐ์—ด]);

 

 

 

 


 

 

 

๋ Œ๋”๋ง๋˜๋Š” ํ™”๋ฉด

์ฒ˜์Œ mount๋  ๋•Œ๋ฅผ ์ œ์™ธํ•˜๊ณค update๋ฅผ ์ถœ๋ ฅํ•˜๊ณ  ์žˆ์Œ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

 


 

 

๐Ÿ’ก์ •๋ฆฌ

  
์‹คํ–‰ ์‹œ์  ์ฝ”๋“œ ์˜ˆ์‹œ ์„ค๋ช…
Mount useEffect(() => {}, []) ์ฒ˜์Œ ๋ Œ๋”๋ง๋  ๋•Œ ํ•œ ๋ฒˆ๋งŒ ์‹คํ–‰
Update useEffect(() => {}, [dep]) ํŠน์ • ๊ฐ’(dep)์ด ๋ฐ”๋€” ๋•Œ๋งˆ๋‹ค ์‹คํ–‰
Unmount useEffect(() => return () => {}, []) ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์‚ฌ๋ผ์งˆ ๋•Œ(clean-up) ์‹คํ–‰
๋ฌด์กฐ๊ฑด ์‹คํ–‰ useEffect(() => {}) ๋ชจ๋“  ๋ Œ๋”๋ง๋งˆ๋‹ค ์‹คํ–‰(์˜์กด์„ฑ ๋ฐฐ์—ด ์—†์Œ)
 

React์—์„œ useEffect๋Š” ๋‹จ์ˆœํ•œ ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ ์ฒ˜๋ฆฌ ๋„๊ตฌ๊ฐ€ ์•„๋‹ˆ๋ผ, ์ปดํฌ๋„ŒํŠธ์˜ ๋ผ์ดํ”„์‚ฌ์ดํด์„ ์„ธ๋ฐ€ํ•˜๊ฒŒ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ•๋ ฅํ•œ ๋„๊ตฌ์ด๋‹ค.

ํŠนํžˆ dependency array์˜ ํ™œ์šฉ์€ ๋ฆฌ๋ Œ๋”๋ง ์ตœ์ ํ™”์™€ ์œ ์ง€๋ณด์ˆ˜์„ฑ ์ธก๋ฉด์—์„œ ํ•„์ˆ˜์ ์ธ ๊ฐœ๋…์ด๋‹ค.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

*Ref

https://ko.react.dev/reference/react/useEffect

 

useEffect – React

The library for web and native user interfaces

ko.react.dev

 

 

 

์„ค๋ช…์ด ๋ถ€์กฑํ•œ ๋ถ€๋ถ„์ด๋‚˜ ํ”ผ๋“œ๋ฐฑ์€ ๋Œ“๊ธ€๋กœ ๋‚จ๊ฒจ์ฃผ์„ธ์š”!

๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค โ˜บ๏ธ

728x90