React - useEffect, useCallback

2022. 4. 11. 16:25ใ†React

React - useEffect, useCallback

 

udemy ๋ฆฌ์•กํŠธ ๊ฐ•์˜์—์„œ ํ•™์Šตํ•œ ๋‚ด์šฉ์„ ์ •๋ฆฌํ•˜๊ณ ์ž ์“ด๋‹ค.

 

์šฐ์„  useEffect ๊ฐœ๋…์„ ๋ณด๋ฉด ์ด๋Š” ๋ฆฌ์•กํŠธ์—์„œ ์ œ๊ณตํ•˜๋Š” ํ›…์ธ๋ฐ ๋ฆฌ์•กํŠธ ๋‚ด๋ถ€์ ์œผ๋กœ UI๋ฅผ ์ง์ ‘ ๋ณ€ํ™”์‹œํ‚ค๋Š” ๋กœ์ง์ด ์•„๋‹Œ ๋ถ€๋ถ„์„ ๋Œ€๋ถ€๋ถ„ ์ด๊ณณ์— ์ •์˜ํ•œ๋‹ค. ์ด๋ฅผ side-effect๋ผ๊ณ  ๋ถ€๋ฅด๋Š”๋ฐ ๋ถ€์ž‘์šฉ์ด๋ผ๋Š” ๋œป์€ ์•„๋‹ˆ๊ณ  ์‚ฌ์ด๋“œ์—์„œ ์ผ์–ด๋‚˜๋Š” ์ดํŽ™ํŠธ ์ •๋„๋กœ ์ƒ๊ฐํ•˜๋ฉด ๋  ๊ฒƒ ๊ฐ™๋‹ค.

 

๊ทธ๋Ÿผ useEffect๋ฅผ ์™œ ์“ธ๊นŒ? 

์ฒซ ๋ฒˆ์งธ๋กœ ์•ž์„œ๋งํ•œ UI๋ฅผ ๋ณ€ํ™”์‹œํ‚ค๋Š” ๋กœ์ง์ด ์•„๋‹Œ ๊ฒฝ์šฐ ์ •ํ™•ํ•˜๊ฒŒ ๋ถ„๋ฆฌ์‹œํ‚ค๊ธฐ ์œ„ํ•ด์„œ๊ฐ€ ์ฒซ ๋ฒˆ์งธ ์ด์œ ์ด๊ณ , ๋‘ ๋ฒˆ์งธ๋กœ๋Š” dependencies๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์„ ๋–„ ์ด๋Š” ์ฒ˜์Œ ์‹œ์ž‘ํ•  ๋•Œ ํ•œ๋ฒˆ๋งŒ ์ดํŒฉํŠธ ํšจ๊ณผ๋ฅผ ์ค„ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. 

 

๋‘ ๋ฒˆ์งธ ์ด์œ ์—์„œ ์‚ดํŽด๋ณด๋ฉด ์‚ฌ์ดํŠธ์— ๋“ค์–ด๊ฐ€์ž๋งˆ์ž api๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๊ฒฝ์šฐ useEffect ๋‚ด๋ถ€์—์„œ ์ •์˜ํ•จ์œผ๋กœ์จ ์ฒ˜์Œ ๋žœ๋”๋ง์ด ์ผ์–ด๋‚œ ์ดํ›„์— ์‹คํ–‰๋˜๊ณ  ๊ทธ ์ดํ›„๋กœ๋Š” ์‹คํ–‰์ด ๋˜์ง€ ์•Š๋Š”๋‹ค. ์ด๋Š” useEffect ๋‚ด๋ถ€์— ๋“ค์–ด๊ฐ„ ๋ถ€๋ถ„์ด ์•„๋‹Œ ๋ถ€๋ถ„์—์„œ ๋ณ€ํ™”๊ฐ€ ์ผ์–ด๋‚ฌ์„ ๋•Œ useEffect ๋‚ด๋ถ€์˜ ๊ฐ’์€ ๋žœ๋”๋ง์ด ๋˜์ง€ ์•Š๊ฒŒ ํ•จ์œผ๋กœ์จ ์„ฑ๋Šฅ์ด ์ €ํ•˜๋˜๋Š” ๊ฒƒ์„ ๋ง‰์„ ์ˆ˜ ์žˆ๋‹ค.

 

๊ทธ๋ฆฌ๊ณ  useEffect์— ๋‘๋ฒˆ์งธ ์ธ์ž์ธ dependencies์—๋Š” useEffect ๋‚ด๋ถ€์—์„œ ์‚ฌ์šฉํ•œ ์™ธ๋ถ€ ๋ณ€์ˆ˜๋“ค์„ ์ ์–ด์ค˜์•ผํ•œ๋‹ค. 

์ด์œ ๋Š” ์™ธ๋ถ€์˜ ๊ฐ’์€ ์–ธ์ œ๋“ ์ง€ ๋ณ€ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด์— ์˜ํ•œ ๋ถˆํ•„์š”ํ•œ ๋ Œ๋”๋ง์„ ๋ง‰๊ธฐ ์œ„ํ•ด์„œ์ด๋‹ค. dependencies์— ๋ณ€์ˆ˜๋ฅผ ์ •์˜ํ•ด ๋†“์œผ๋ฉด ํ•ด๋‹น ๋ณ€์ˆ˜๊ฐ€ ๋ณ€ํ•˜์ง€ ์•Š๋Š”์ด์ƒ useEffect ๋‚ด๋ถ€์˜ ํ•จ์ˆ˜๋Š” ๋ Œ๋”๋ง๋˜์ง€ ์•Š๋Š”๋‹ค. ๋”ฐ๋ผ์„œ useEffect๋‚ด๋ถ€์—๋Š” ์‚ฌ์šฉํ•œ ์™ธ๋ถ€๋ณ€์ˆ˜์— ๋Œ€ํ•ด dependencies์— ์ •์˜ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค. 

 

ํ•˜์ง€๋งŒ ์ฃผ์˜ํ•  ์ ์ด ์žˆ๋‹ค. dependencies์— ์ •์˜ํ•  ๋•Œ ํƒ€์ž…์ด ์›์‹œํƒ€์ž…์ด ์•„๋‹Œ ์ฐธ์กฐ ํƒ€์ž…์ด๋ผ๋ฉด useCallback, useMemo ๋“ฑ์œผ๋กœ ํ•ด๋‹น ํƒ€์ž…์„ ๊ฐ์‹ธ์ค˜์•ผ ํ•œ๋‹ค. ์ด์œ ๋Š” ์ฐธ์กฐํƒ€์ž…์€ ์ด๋ฆ„๊ณผ ๊ฐ’์ด ๊ฐ™์•„๋„ ์ฃผ์†Œ๊ฐ€ ๋‹ค๋ฅด๋‹ค๋ฉด ๋‹ค๋ฅด๋‹ค๊ณ  ํŒ๋ณ„ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ด ๋•Œ๋ฌธ์— useEffect๋‚ด๋ถ€์—์„œ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ํ•ด๋‹น ์™ธ๋ถ€ํ•จ์ˆ˜๋ฅผ useCallback์œผ๋กœ ๋ฌถ์–ด์ค˜์•ผ ํ•œ๋‹ค. 

 

๊ทธ๋Ÿผ ์—ฌ๊ธฐ์„œ useCallback, useMemo๋Š” ๋ญ˜๊นŒ?

์‰ฝ๊ฒŒ ์ƒ๊ฐํ•˜๋ฉด ๋ฆฌ์•กํŠธ ๋‚ด๋ถ€์—์„œ ํ•ด๋‹น ํ•จ์ˆ˜๋ฅผ ์ฒ˜์Œ ๋žœ๋”๋งํ•  ๋•Œ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅํ•˜๊ณ  ์ด๋ฆ„๊ณผ ๊ฐ’์ด ๊ฐ™๋‹ค๋ฉด ๊ฐ™๋‹ค๊ณ  ํŒ๋ณ„ํ•˜๋Š” ํ›…์ด๋ผ๊ณ  ๋ณด๋ฉด ๋œ๋‹ค. (ํ•„์ž๋Š” ์ด๋ ‡๊ฒŒ ์ดํ•ดํ•จ)

 

์•„๋ž˜ ์˜ˆ์‹œ๋ฅผ ๋ณด๋ฉด useCallback์˜ ์˜ˆ์‹œ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. (udemy ๊ฐ•์˜ ์ค‘, useMemo๋Š” ์‚ฌ์šฉํ•˜์ง€ ์•Š์Œ.)

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

import MoviesList from './components/MoviesList';
import './App.css';

function App() {
  const [movies, setMovies] = useState([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);

  const fetchMoviesHandler = useCallback(async () => { //์„œ๋ฒ„๋กœ ๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ด.
    try {
      setLoading(true);
      setError(null); 
      const response = await fetch('https://swapi.dev/api/film/');
      if(!response.ok) {
        throw new Error("something wrong")
      }
      const data = await response.json();
      const transformedMovies = data.results.map((movieData) => {
          return {
            id: movieData.episode_id,
            title: movieData.title,
            openingText: movieData.opening_crawl,
            releaseDate: movieData.release_date
          }
      });
      setMovies(transformedMovies);
    }catch (error) {
      setError(error.message);
    }
    setLoading(false);
  }, []); //๋””ํŽœ๋˜์‹œ๊ฐ€ ์—†๋Š” ์ด์œ ๋Š” ์™ธ๋ถ€์˜ ๊ฐ’์ด useCallback์— ๋ž˜ํ•‘๋œ ํ•จ์ˆ˜์—์„œ ์‚ฌ์šฉ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ.


  
  useEffect(()=> {
    fetchMoviesHandler();
  }, [fetchMoviesHandler]);

  let content = <p>Found no movies</p>
  
  if (movies.length > 0) {
    content = <MoviesList movies={movies} />
  }
 
  if (error) {
    content = <p>{error}</p>;
  }

  //์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์—๋Ÿฌ๊ฐ€ ์ฒ˜์Œ์— ์—†์œผ๋‹ˆ๊นŒ ๋งจ ๋งˆ์ง€๋ง‰ ๋‹จ์— ๋‘”๋‹ค. ์ด๊ฑธ ์œ—๋‹จ์œผ๋กœ ์˜ฌ๋ฆฌ๋ฉด ๋น ๋ฅด๊ฒŒ ์‹คํ–‰๋˜๊ธฐ์— loading์ด ๋ณด์ด์ง€์•Š๋Š”๋‹ค.
  //์ด๋ฅผ ์œ—๋‹จ์œผ๋กœ ์˜ฌ๋ฆฌ๋ฉด error๋ถ€๋ถ„์„ setTimeout์„ ํ•˜๊ฒŒ ๋˜๋ฉด loading์ด ๋ณด์ธ๋‹ค. 
  if (loading) {
    content = <p>currently loading...</p>;
  }  


  

  return (
    <React.Fragment>
      <section>
        <button onClick={fetchMoviesHandler}>Fetch Movies</button>
      </section>
      <section>
        {content}
      </section>
    </React.Fragment>
  );
}


export default App;

 

 

'React' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

React - useRef  (0) 2022.05.07
State ๋Œ์–ด์˜ฌ๋ฆฌ๊ธฐ  (0) 2022.05.07
React - ํ•ฉ์„ฑ  (0) 2022.05.07