컴포넌트가 랜더링될 때마다 특정 작업을 수행하도록 설정할 수 있는 Hooks이다.

useEffect(() => {
    // 함수 영역(State가 바뀔때 함수 호출하여 라이프 사이클 최적화 함)
    // componentDidMount, componentDidUpdate

}, ['State가 바뀔때 마다 실행']); // [] 번째 인수는 배열

//Cleanup
useEffect( () => {
    return() => {
       // useEffect Cleanup 실행
       // 종료시에 활용( 예 로컬 스토리지 삭제)
    }
})

useEffect(() => {}) // 모든 render일때 다시 실행 (dependencies없기때문에)
useEffect(() => {},[]) // 빈 배열, 아무것도 없을 경우 첫 render일때만 실행
useEffect(() => {},[state]) // state가 바뀔 때 마다 호출

예제

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

const Child = () => {
  return(
    <div>
      <p>Child Component~!!!</p>
    </div>
  );
};

const UseEffect = () => {
  const [show, setShow] = useState(false);

  const onClick = () => {
    setShow(!show);
  }

  // 모든 render일때 다시 실행
  // useEffect( () => {
  //   console.log('모든 render일때 다시 실행');
  // })
  // 첫 render일때만 실행
  // useEffect( () => {
  //   console.log('첫 render일때만 실행');
  // },[])
  // state가 바뀔 때 마다 실행
  useEffect( () => {
    console.log('state가 바뀔 때 마다 실행');
  },[show])

  return(
    <div>
      <button onClick={ onClick }>클릭~!!!</button>
      {show ? <Child /> : null}
    </div>
  );
};

export default UseEffect;

Child Cleanup

import React, { useEffect, useRef, useState } from "react";
 
const Child = () => {
  console.log("  Child render start");
  const inputRef = useRef();
  const [text, setText] = useState(() => {
    console.log("  Child useState");
    return "";
  });
  useEffect(() => {
    console.log("  Child useEffect, no deps");
    return () => {
      console.log("  Child useEffect [Cleanup], no deps");
    };
  });
  useEffect(() => {
    console.log("  Child useEffect, empty deps");
    inputRef.current.focus();
    return () => {
      console.log("  Child useEffect [Cleanup], empty deps");
    };
  }, []);
  useEffect(() => {
    console.log("  Child useEffect, [text]");
    return () => {
      console.log(" Child useEffect [Cleanup], [text]");
    };
  }, [text]);
 
  function handleChange(event) {
    setText(event.target.value);
  }
 
  return (
    <>
      <input type="text" onChange={handleChange} ref={inputRef} />
      <p>{text}</p>
      {console.log("  Child render End")}
    </>
  );
};
 
const Hookflow = () => {
  console.log("App render Start");
  const [show, setShow] = useState(() => {
    console.log("APP useStgate");
    return false;
  });
 
  useEffect(() => {
    console.log("App useEffect, no deps");
    return () => {
      console.log("App useEffect [Cleanup], no deps");
    };
  });
  useEffect(() => {
    console.log("App useEffect, empty deps");
    return () => {
      console.log("App useEffect [Cleanup], empty deps");
    };
  }, []);
  useEffect(() => {
    console.log("App useEffect, [show]");
    return () => {
      console.log("App useEffect [Cleanup], [show]");
    };
  }, [show]);
 
  function handleClick() {
    setShow((prev) => !prev);
  }
 
  return (
    <div>
      <h1>Hook Flow </h1>
      <button onClick={handleClick}>Search</button>
      {show ? <Child /> : null}
      {console.log("App render End")}
    </div>
  );
};
 
export default Hookflow;