1 ๋ถ„ ์†Œ์š”

useEffect?๐Ÿ“

Side Effect : ๋ถ€์ˆ˜์ ์ธ ํšจ๊ณผ๋กœ ํ•จ์ˆ˜๊ฐ€ ์–ด๋–ค๋™์ž‘์„ ํ• ๋•Œ input, output์ด์™ธ์˜ ๋‹ค๋ฅธ๊ฐ’์ด ์กฐ์ž‘๋œ๋‹ค๋ฉด ๊ทธ๊ฒƒ์€ side Effect๊ฐ€ ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค.
let count = 0;
function greetWithSideEffect(name) {
  // Input
  count = count + 1; // Side Effect!
  return `${name}๋‹˜ ์•ˆ๋…•ํ•˜์„ธ์š”!`; // Output
}
side Effect์˜ ์˜ˆ์‹œ


function greetWithSideEffect({ name }) {
  // Input
  // Bad!
  document.title = `${name}๋‹˜ ์•ˆ๋…•ํ•˜์„ธ์š”!`; // Side Effect

  return <div>{`${name}๋‹˜ ์•ˆ๋…•ํ•˜์„ธ์š”!`}</div>; // Output
}
side Effect์˜ ์ž˜๋ชป๋œ ์˜ˆ์‹œ)=>


ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์˜ ๋ฆฌํ„ด ๊ฐ’์€ UI ์š”์†Œ์ด๊ณ , state, props์˜ ๋ณ€ํ™”๊ฐ€ ์žˆ์„ ๋•Œ๋งˆ๋‹ค ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋œ๋‹ค. ์ด ๋ง์€ ๋งค ๋ Œ๋”๋ง ๋•Œ๋งˆ๋‹ค ํ•จ์ˆ˜ body์— ์žˆ๋Š” ๋ Œ๋”๋ง๊ณผ ๋ฌด๊ด€ํ•œ ๋กœ์ง์ด ๋ Œ๋”๋ง ๊ณผ์ •์—์„œ ์‹คํ–‰๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋ Œ๋”๋ง ์ž์ฒด์— ์˜ํ–ฅ์„ ์ค˜ ์„ฑ๋Šฅ ์ƒ ์•…์˜ํ–ฅ์„ ๋ผ์น  ์ˆ˜๋„ ์žˆ๋‹ค.




useEffect : ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ์˜ ํ›…(๊ธฐ์กด์˜ ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ์—์„œ ํ•  ์ˆ˜ ์—†์—ˆ๋˜ ๋‹ค์–‘ํ•œ ์ž‘์—…์„ ํ•  ์ˆ˜ ์žˆ๊ฒŒํ•ด์ฃผ๋Š” ๊ธฐ๋Šฅ)์œผ๋กœ์„œ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ Œ๋”๋ง ์ดํ›„์— ์ˆ˜ํ–‰ํ•ด์•ผ ํ•  ์ผ์„ ๋ฆฌ์•กํŠธ์— ์ „๋‹ฌํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. ์ฆ‰)Side Effect๊ฐ€ ๋ Œ๋”๋ง์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๋„๋ก ์„ค๊ณ„๋จ
import { useEffect } from "react"

// ์‚ฌ์šฉ๋ฒ•
useEffect( ์‹คํ–‰์‹œํ‚ฌ ๋™์ž‘, [ ํƒ€์ด๋ฐ ] )
document.addEventListener("ํƒ€์ด๋ฐ", ์‹คํ–‰์‹œํ‚ฌ ๋™์ž‘) // ์ถ”์ƒํ™” ํ•œ ์˜ˆ์‹œ

// ๋งค ๋ Œ๋”๋ง๋งˆ๋‹ค Side Effect๊ฐ€ ์‹คํ–‰๋˜์–ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ
useEffect(() => {
  // Side Effect
})

// Side Effect๊ฐ€ ์ฒซ ๋ฒˆ์งธ ๋ Œ๋”๋ง ์ดํ›„ ํ•œ๋ฒˆ ์‹คํ–‰ ๋˜๊ณ ,
// ์ดํ›„ ํŠน์ • ๊ฐ’์˜ ์—…๋ฐ์ดํŠธ๋ฅผ ๊ฐ์ง€ํ–ˆ์„ ๋•Œ๋งˆ๋‹ค ์‹คํ–‰๋˜์–ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ
useEffect(() => {
  // Side Effect
}, [value])

// Side Effect๊ฐ€ ์ฒซ ๋ฒˆ์งธ ๋ Œ๋”๋ง ์ดํ›„ ํ•œ๋ฒˆ ์‹คํ–‰ ๋˜๊ณ ,
// ์ดํ›„ ์–ด๋–ค ๊ฐ’์˜ ์—…๋ฐ์ดํŠธ๋„ ๊ฐ์ง€ํ•˜์ง€ ์•Š๋„๋ก ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ
useEffect(() => {
  // Side Effect
}, [])
useEffect์˜ ์‚ฌ์šฉ๋ฒ•




Clean up Effect : useEffect์˜ return๊ฐ’์— ์ด์ „์— ์ผ์œผํ‚จ Side Effect๋ฅผ ์ •๋ฆฌํ•˜๋Š”code๋ฅผ ์ž‘์„ฑํ•˜๋Š” ํ•˜๋Š”๊ฒƒ์ด๋‹ค.
useEffect(() => {
  function handleScroll() {
    console.log(window.scrollY);
  }

  document.addEventListener("scroll", handleScroll);
  return () => {
    document.removeEventLisnter("scroll", handleScroll);
  };
}, []);


return๊ฐ’์— ์ด๋ฒคํŠธ๋ฅผ ์ง€์›Œ์ฃผ๋Š” ๋กœ์ง์„ ์ƒ์„ฑํ•จ์œผ๋กœ์จ ํŽ˜์ด์ง€๋ฅผ ์ด๋™ํ• ๋•Œ(component๊ฐ€ unmount๋ ๋•Œ)

์ด๋ฒคํŠธ๊ฐ€ ์ •๋ฆฌ๋˜์–ด ์„ฑ๋Šฅ์ €ํ•˜๋ฅผ ๋ง‰์„ ์ˆ˜ ์žˆ์Œ.


const App = () => {
  const [count, setCount] = useState(0);

  console.log("render", count);

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

  return <div onClick={() => setCount(count + 1)}>ํ•˜์ž‰</div>;
};

export default Foo;


๋ฒ„ํŠผ์„ ํ•œ๋ฒˆ ๋ˆŒ๋ €์„๋•Œ ์ฐํžˆ๋Š” ์ฝ˜์†”์˜ ๊ฐ’๋“ค์„ ์˜ˆ์ƒํ•ด๋ณด์ž.


render, 0
useEffect Callback, 0

// ํด๋ฆญ

render, 1
cleanUp, 0
useEffect Callback, 1


์ด code๋ฅผ ํ†ตํ•ด cleanup ํ•จ์ˆ˜๊ฐ€ deps์— ์•„๋ฌด๊ฐ’๋„ ๋„ฃ์ง€์•Š์•˜์„ ๊ฒฝ์šฐ์—๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ unmount ๋ ๋•Œ๋งŒ ์‹คํ–‰๋˜๊ณ 


deps์— ํŠน์ •๊ฐ’์„ ๋„ฃ์—ˆ๋‹ค๋ฉด ๊ทธ ๊ฐ’์ด ์—…๋ฐ์ดํŠธ๋˜๊ธฐ ์ง์ „์— ์‹คํ–‰๋˜๋Š”๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.


์ฐธ๊ณ * deps๋Š” useEffect์˜ 2๋ฒˆ์งธ ์ธ์ž์ธ [] ๋ฐฐ์—ด์„ ๋œปํ•œ๋‹ค.

์—…๋ฐ์ดํŠธ: