ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [React] Effect Hook
    codeStates front-end/React 2023. 2. 2. 17:46
    ๋ฐ˜์‘ํ˜•

     

     

     

     

     

     

     

     

     

    ๐Ÿ“ŒEffect Hook

     

    React ์ปดํฌ๋„ŒํŠธ ์™ธ๋ถ€์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ณ  ๋ฐ›์•„์˜ค๋Š” ๊ณผ์ •

     

     

    ๐Ÿ”—Side Effect (๋ถ€์ˆ˜ ํšจ๊ณผ)

     

    React์—์„œ ์ปดํฌ๋„Œํ‹‘ ๋‚ด์—์„œ fetch๋ฅผ ์‚ฌ์šฉํ•ด API ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ์ด๋ฒคํŠธ๋ฅผ ํ™œ์šฉํ•ด

    DOM ์ง์ ‘ ์กฐ์ž‘ํ•  ๋•Œ Side Effect๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค๊ณ  ํ•œ๋‹ค.

     

    -------------------------------

     

    ๐Ÿ’ก fetch๊ฐ€ ๋ญ์—์š”? ์„œ๋ฒ„์— ๋„คํŠธ์›Œํฌ ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ  ์ƒˆ๋กœ์šด ์ •๋ณด๋ฅผ ๋ฐ›์•„์˜ค๋Š” ์ผ

     

    // fetch() ๊ธฐ๋ณธ ๋ฌธ๋ฒ•
    let promise = fetch(url, [options])
    //fetch ํ•จ์ˆ˜๋Š” API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐฑ์—”๋“œ ์„œ๋ฒ„์™€ ๋น„๋™๊ธฐ ์š”์ฒญ์„ ํ•˜๋Š” ๋ฐฉ์‹ ์ค‘ ํ•˜๋‚˜
    //fetch API๋Š” 3๊ฐœ์˜ interfeace๋ฅผ ๋„์ž…ํ•˜๊ณ  ์žˆ๋Š”๋ฐ Headers, Request, Response์ด๋‹ค.
    //url-์ ‘๊ทผํ•˜๊ณ ์ž ํ•˜๋Š” URL
    //options - ์„ ํƒ ๋งค๊ฐœ๋ณ€์ˆ˜, mehtod๋‚˜ header ๋“ฑ์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.
    fetch('url')
    .then(response => response.json())
    .then(response => data.filter(item => item.isRequired));

     

    -------------------------------

     

    // ์ „์—ญ ๋ณ€์ˆ˜ foo๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ์˜ˆ์ œ
    let foo = 'hello';
    
    function bar() {
      foo = 'world';
    }
    
    bar(); // bar๋Š” Side Effect๋ฅผ ๋ฐœ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค!

     

    ๐Ÿ”—Pure Function(์ˆœ์ˆ˜ ํ•จ์ˆ˜)

     

    ์˜ค์ง ํ•จ์ˆ˜์˜ ์ž…๋ ฅ๋งŒ์ด ํ•จ์ˆ˜์˜ ๊ฒฐ๊ณผ์— ์˜ํ–ฅ์„ ์ฃผ๋Š” ํ•จ์ˆ˜๋ฅผ ์˜๋ฏธ

     

    ์ˆœ์ˆ˜ํ•จ์ˆ˜ ์กฐ๊ฑด

     

    ํ•จ์ˆ˜์˜ ์ž…๋ ฅ์ด ์•„๋‹Œ ๋‹ค๋ฅธ ๊ฐ’์ด ํ•จ์ˆ˜์˜ ๊ฒฐ๊ณผ์— ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š” ๊ฒฝ์šฐ, ์ˆœ์ˆ˜ ํ•จ์ˆ˜ x

    ์ž…๋ ฅ์œผ๋กœ ์ „๋‹ฌ๋œ ๊ฐ’์„ ์ˆ˜์ • x

    ์ˆœ์ˆ˜ ํ•จ์ˆ˜์—๋Š” ๋„คํŠธ์›Œํฌ ์š”์ฒญ๊ณผ ๊ฐ™์€ Side Effect x

    ์–ด๋– ํ•œ ์ „๋‹ฌ์ธ์ž๊ฐ€ ์ฃผ์–ด์ง„ ๊ฒฝ์šฐ, ํ•ญ์ƒ ๋˜‘๊ฐ™์€ ๊ฐ’์ด ๋ฆฌํ„ด๋จ์„ ๋ณด์žฅ

     

    function upper(str) {
      return str.toUpperCase(); // toUpperCase ๋ฉ”์†Œ๋“œ๋Š” ์›๋ณธ์„ ์ˆ˜์ •ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค (Immutable)
    }
    
    upper('hello') // 'HELLO'

     

     

    ๐Ÿ’ก

    • Math.random()์€ ์ˆœ์ˆ˜ ํ•จ์ˆ˜๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. ์™œ์ผ๊นŒ์š”?
    • ์–ด๋–ค ํ•จ์ˆ˜๊ฐ€ fetch API๋ฅผ ์ด์šฉํ•ด AJAX ์š”์ฒญ์„ ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ด…์‹œ๋‹ค. ์ด ํ•จ์ˆ˜๋Š” ์ˆœ์ˆ˜ ํ•จ์ˆ˜๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. ์™œ์ผ๊นŒ์š”?

     

    ๐Ÿ“–

    • random ๊ฐ’์€ ๋ง๊ทธ๋Œ€๋กœ ๊ฐ’์ด ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ์ˆœ์ˆ˜ํ•จ์ˆ˜๊ฐ€ ๋  ์ˆ˜ ์—†๋‹ค
    • ๋„คํŠธ์›Œํฌ ์ƒํ™ฉ, ์„œ๋ฒ„์ƒํƒœ์— ๋”ฐ๋ผ ์‘๋‹ต์ฝ”๋“œ๊ฐ€ ๋‹ฌ๋ผ์ง€๊ธฐ ๋•Œ๋ฌธ์— ์˜ˆ์ธก ๋ถˆ๊ฐ€๋Šฅ

     

     

    ๐Ÿ‘‰๐Ÿผ๐Ÿ‘‰๐Ÿผ AJAX์š”์ฒญ์ด ํ•„์š”ํ•˜๊ฑฐ๋‚˜, localStorage ๋˜๋Š” ํƒ€์ด๋จธ๊ฐ™์€ react์™€๋Š” ์ƒ๊ด€์—†๋Š” API๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ๋ฐœ์ƒ

              React ์ž…์žฅ์—์„œ๋Š” ์ „๋ถ€ Side Effect ์ด๊ฒƒ์„ ๋‹ค๋ฅด๊ธฐ ์œ„ํ•ด Effect Hook์„ ์ œ๊ณต

     

     

     

     

     

    ๐Ÿ“Effect Hook - useEffect

    useEffect๋Š” ์ปดํฌ๋„ŒํŠธ ๋‚ด์—์„œ Side effect(ํŠน์ • ์ž‘์—…)๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋Š” Hook

    ์ด ์ปดํฌ๋„ŒํŠธ์—์„œ ์‹คํ–‰ํ•˜๋Š” Side effect๋Š” ๋ธŒ๋ผ์šฐ์ € API๋ฅผ ์ด์šฉํ•˜์—ฌ, ํƒ€์ดํ‹€์„ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ

     

     

    API

     

    useEffect์˜ ์ฒซ ๋ฒˆ์งธ ์ธ์ž๋Š” ํ•จ์ˆ˜

    ํ•ด๋‹น ํ•จ์ˆ˜ ๋‚ด์—์„œ side effect๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ๋œ๋‹ค.

    ์ƒˆ๋กญ๊ฒŒ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ Œ๋”๋ง ๋  ๋•Œ Effect Hook์ด ์‹คํ–‰

     

     

    • ์ปดํฌ๋„ŒํŠธ ์ƒ์„ฑ ํ›„ ์ฒ˜์Œ ํ™”๋ฉด์— ๋ Œ๋”๋ง(ํ‘œ์‹œ)
    • ์ปดํฌ๋„ŒํŠธ์— ์ƒˆ๋กœ์šด props๊ฐ€ ์ „๋‹ฌ๋˜๋ฉฐ ๋ Œ๋”๋ง
    • ์ปดํฌ๋„ŒํŠธ์— ์ƒํƒœ(state)๊ฐ€ ๋ฐ”๋€Œ๋ฉฐ ๋ Œ๋”๋ง

     

     

    Hook์„ ์“ธ ๋•Œ ์ฃผ์˜ํ•  ์ 

     

    • ์ตœ์ƒ์œ„์—์„œ๋งŒ Hook์„ ํ˜ธ์ถœํ•œ๋‹ค.
    • ๋ฆฌ์•กํŠธ ํ•จ์ˆ˜ ๋‚ด์—์„œ Hook์„ ํ˜ธ์ถœํ•œ๋‹ค.

     

     

     

    ๐Ÿ”—์กฐ๊ฑด๋ถ€ effect ๋ฐœ์ƒ(dependency array)

     

    useEffect์˜ ๋‘ ๋ฒˆ์งธ ์ธ์ž๋Š” ๋ฐฐ์—ด

    ์กฐ๊ฑด์€ boolean ํ˜•ํƒœ์˜ ํ‘œํ˜„์‹์ด ์•„๋‹Œ, ์–ด๋–ค ๊ฐ’์˜ ๋ณ€๊ฒฝ์ด ์ผ์–ด๋‚  ๋•Œ๋ฅผ ์˜๋ฏธ

    ๋”ฐ๋ผ์„œ ํ•ด๋‹น ๋ฐฐ์—ด์—” ์–ด๋–ค ๊ฐ’์˜ ๋ชฉ๋ก์ด ๋“ค์–ด๊ฐ„๋‹ค(์ข…์†์„ฑ ๋ฐฐ์—ด)

     

    API

     

    useEffect(ํ•จ์ˆ˜, [์ข…์†์„ฑ1, ์ข…์†์„ฑ2, ...])

     

    useEffect์˜ ๋‘ ๋ฒˆ์งธ ์ธ์ž๋Š” ์ข…์†์„ฑ ๋ฐฐ์—ด

    ๋ฐฐ์—ด ๋‚ด์˜ ์ข…์†์„ฑ1, ๋˜๋Š” ์ข…์†์„ฑ2์˜ ๊ฐ’์ด ๋ณ€ํ•  ๋•Œ, ์ฒซ ๋ฒˆ์งธ ์ธ์ž์˜ ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰

     

     

    ๐Ÿ”—๋‹จ ํ•œ๋ฒˆ๋งŒ ์‹คํ–‰๋˜๋Š” Effect ํ•จ์ˆ˜

     

    • ๋นˆ ๋ฐฐ์—ด ๋„ฃ๊ธฐ : ๋นˆ ๋ฐฐ์—ด์„ useEffect์˜ ๋‘ ๋ฒˆ์งธ ์ธ์ž๋กœ ์‚ฌ์šฉํ•˜๋ฉด, ์ด๋•Œ์—๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ฒ˜์Œ ์ƒ์„ฑ๋  ๋•Œ๋งŒ effect ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋œ๋‹ค. ๋Œ€ํ‘œ์ ์œผ๋กœ ์ฒ˜์Œ ๋‹จ ํ•œ ๋ฒˆ, ์™ธ๋ถ€ API๋ฅผ ํ†ตํ•ด ๋ฆฌ์†Œ์Šค๋ฅผ ๋ฐ›์•„์˜ค๊ณ  ๋” ์ด์ƒ API ํ˜ธ์ถœ์ด ํ•„์š”ํ•˜์ง€ ์•Š์„ ๋•Œ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
      • useEffect(ํ•จ์ˆ˜, [])
    • ์•„๋ฌด๊ฒƒ๋„ ๋„ฃ์ง€ ์•Š๊ธฐ : ๊ธฐ๋ณธ ํ˜•ํƒœ์˜ useEffect๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ฒ˜์Œ ์ƒ์„ฑ๋˜๊ฑฐ๋‚˜, props๊ฐ€ ์—…๋ฐ์ดํŠธ๋˜๊ฑฐ๋‚˜, ์ƒํƒœ(state)๊ฐ€ ์—…๋ฐ์ดํŠธ๋  ๋•Œ effect ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋œ๋‹ค.
      • useEffect(ํ•จ์ˆ˜)

     

     

    ๐Ÿ”—Data Fetching : ํ•„ํ„ฐ๋ง ์˜ˆ์ œ ๋‹ค์‹œ ๋ณด๊ธฐ

     

    ๋ชฉ๋ก ๋‚ด ํ•„ํ„ฐ๋ง์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋‘ ๊ฐ€์ง€ ์ ‘๊ทผ์ด ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค

     

    1. ์ปดํฌ๋„ŒํŠธ ๋‚ด์—์„œ ํ•„ํ„ฐ๋ง: ์ „์ฒด ๋ชฉ๋ก ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๊ณ , ๋ชฉ๋ก์„ ๊ฒ€์ƒ‰์–ด๋กœ filter ํ•˜๋Š” ๋ฐฉ๋ฒ•
    2. ์ปดํฌ๋„ŒํŠธ ์™ธ๋ถ€์—์„œ ํ•„ํ„ฐ๋ง: ์ปดํฌ๋„ŒํŠธ ์™ธ๋ถ€๋กœ API ์š”์ฒญ์„ ํ•  ๋•Œ, ํ•„ํ„ฐ๋ง ํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ›์•„์˜ค๋Š” ๋ฐฉ๋ฒ• (๋ณดํ†ต, ์„œ๋ฒ„์— ๋งค๋ฒˆ ๊ฒ€์ƒ‰์–ด์™€ ํ•จ๊ป˜ ์š”์ฒญํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์ด์— ํ•ด๋‹น)

     

    ์žฅ๋‹จ์ 

     

      ์žฅ์  ๋‹จ์ 
    ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์—์„œ ์ฒ˜๋ฆฌ HTTP ์š”์ฒญ์˜ ๋นˆ๋„๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค ๋ธŒ๋ผ์šฐ์ €(ํด๋ผ์ด์–ธํŠธ)์˜ ๋ฉ”๋ชจ๋ฆฌ ์ƒ์— ๋งŽ์€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ–๊ฒŒ ๋˜๋ฏ€๋กœ, ํด๋ผ์ด์–ธํŠธ์˜ ๋ถ€๋‹ด์ด ๋Š˜์–ด๋‚œ๋‹ค
    ์ปดํฌ๋„ŒํŠธ ์™ธ๋ถ€์—์„œ ์ฒ˜๋ฆฌ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ํ•„ํ„ฐ๋ง ๊ตฌํ˜„์„ ์ƒ๊ฐํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค ๋นˆ๋ฒˆํ•œ HTTP ์š”์ฒญ์ด ์ผ์–ด๋‚˜๊ฒŒ ๋˜๋ฉฐ, ์„œ๋ฒ„๊ฐ€ ํ•„ํ„ฐ๋ง์„ ์ฒ˜๋ฆฌํ•˜๋ฏ€๋กœ ์„œ๋ฒ„๊ฐ€ ๋ถ€๋‹ด์„ ๊ฐ€์ ธ๊ฐ„๋‹ค

     

     

    ๐Ÿ”—AJAX ์š”์ฒญ

    useEffect(() => {
      fetch(`http://์„œ๋ฒ„์ฃผ์†Œ/proverbs?q=${filter}`)
        .then(resp => resp.json())
        .then(result => {
          setProverbs(result);
        });
    }, [filter]);

     

     

    ๐Ÿ”—AJAX ์š”์ฒญ์ด ๋งค์šฐ ๋Š๋ฆด ๊ฒฝ์šฐ?

    ๋ชจ๋“  ๋„คํŠธ์›Œํฌ ์š”์ฒญ์ด ํ•ญ์ƒ ์ฆ‰๊ฐ์ ์ธ ์‘๋‹ต์„ ๊ฐ€์ ธ๋‹ค์ฃผ๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.

    ์™ธ๋ถ€ API ์ ‘์†์ด ๋Š๋ฆด ๊ฒฝ์šฐ๋ฅผ ๊ณ ๋ คํ•˜์—ฌ, ๋กœ๋”ฉ ํ™”๋ฉด(loading indicator)์˜ ๊ตฌํ˜„์€ ํ•„์ˆ˜์ 

     

    loading indicator

    const [isLoading, setIsLoading] = useState(true);
    
    // ์ƒ๋žต, LoadingIndicator ์ปดํฌ๋„ŒํŠธ๋Š” ๋ณ„๋„๋กœ ๊ตฌํ˜„ํ–ˆ์Œ์„ ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค
    return {isLoading ? <LoadingIndicator /> : <div>๋กœ๋”ฉ ์™„๋ฃŒ ํ™”๋ฉด</div>}

     

    fetch ์š”์ฒญ์˜ ์ „ํ›„๋กœ setIsLoading์„ ์„ค์ •ํ•ด ์ฃผ์–ด ๋ณด๋‹ค ๋‚˜์€ UX๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

    useEffect(() => {
      setIsLoading(true);
      fetch(`http://์„œ๋ฒ„์ฃผ์†Œ/proverbs?q=${filter}`)
        .then(resp => resp.json())
        .then(result => {
          setProverbs(result);
          setIsLoading(false);
        });
    }, [filter]);

     

    ๋ฐ˜์‘ํ˜•

    ๋Œ“๊ธ€

Designed by Tistory.