βš™οΈFrontend/REACT

[React] useMemo (ft. μž¬μ—°μ‚° μ΅œμ ν™”)

soonybutter 2025. 5. 28. 15:55
728x90

 

 

 

 

 

πŸ’‘μ΅œμ ν™”  

μ½”ν…Œλ₯Ό μ€€λΉ„ν•˜λ©΄μ„œλ„, μ• ν”Œλ¦¬μΌ€μ΄μ…˜ κ°œλ°œμ„ ν•˜λ©΄μ„œλ„ 항상 μ‹ κ²½μ¨μ•Όν•œλ‹€κ³  λˆ„λˆ„νžˆ 듀은 μ½”λ“œ μ΅œμ ν™”.. ! 두λ‘₯.. 

λ¦¬μ•‘νŠΈ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ κ°œλ°œν•  λ•Œ μ—­μ‹œ λ§ˆμ°¬κ°€μ§€μ΄λ‹€.

 

 

λ¦¬μ•‘νŠΈμ—μ„œλŠ” 'λ Œλ”λ§κ³Ό μ—°μ‚°'이 μ„±λŠ₯에 큰 영ν–₯을 λ―ΈμΉœλ‹€.

특히, μƒνƒœ( state) κ°€ 변경될 λ•Œλ§ˆλ‹€ λΆˆν•„μš”ν•œ μ—°μ‚°μ΄λ‚˜ λ Œλ”λ§μ΄ 반볡되면 전체 μ„±λŠ₯이 μ €ν•˜λ  수 μžˆλ‹€.

 

 

 

 

 

 

λ¦¬μ•‘νŠΈ μ΅œμ ν™”λ₯Ό μœ„ν•΄ μ§€μ–‘ν•΄μ•Όν•  μš”μ†Œλ“€μ€ μ•„λž˜μ™€ κ°™λ‹€.

 

1. λΆˆν•„μš”ν•œ λ Œλ”λ§

2. μ»΄ν¬λ„ŒνŠΈ λ‚΄λΆ€μ˜ λΆˆν•„μš”ν•œ μ—°μ‚°

3. μ»΄ν¬λ„ŒνŠΈ λ‚΄λΆ€μ˜ λΆˆν•„μš”ν•œ ν•¨μˆ˜ μž¬μƒμ„±

 

 

 

 

이쀑 useMemo 훅은 React의 λΆˆν•„μš”ν•œ 연산을 막아 μ΅œμ ν™”ν•œλ‹€.

 

 

 

 

 

 


 

 

 

πŸ’‘useMemo 

: νŠΉμ • μ—°μ‚°μ˜ κ²°κ³Όλ₯Ό λ©”λͺ¨μ΄μ œμ΄μ…˜(memoization) ν•˜μ—¬ λΆˆν•„μš”ν•œ μ—°μ‚°(μž¬μ—°μ‚°)을 λ°©μ§€ν•˜λŠ” React Hook.

-> μ˜μ‘΄μ„± 배열에 λͺ…μ‹œλœ 값이 변경될 λ•Œμ—λ§Œ 콜백 ν•¨μˆ˜μ˜ ν•΄λ‹Ή 연산을 λ‹€μ‹œ μˆ˜ν–‰ν•œλ‹€.

κ·Έλ ‡μ§€ μ•ŠμœΌλ©΄, 이전에 κ³„μ‚°λœ 값을 κ·ΈλŒ€λ‘œ μž¬μ‚¬μš©ν•¨.

 

 

*μ›λž˜λŠ” μ»΄ν¬λ„ŒνŠΈκ°€ λ Œλ”λ§ λ λ•Œλ§ˆλ‹€ ν•¨μˆ˜ λ‚΄λΆ€μ˜ 연산이 항상 μž¬μ‹€ν–‰λ˜λŠ”λ°,

이 κ³Όμ •μ—μ„œ 무거운 연산이 λ°˜λ³΅λ˜κ±°λ‚˜ λΆˆν•„μš”ν•œ λ°°μ—΄ 탐색이 μ§€μ†μ μœΌλ‘œ λ°œμƒν•˜λ©΄ μ„±λŠ₯에 뢀담이됨.

 

 

 

 

 

 

useMemoλŠ” μ•„λž˜μ™€ 같은 ν˜•νƒœλ₯Ό κ°€μ§„λ‹€.

const memoizedValue = useMemo(() => {
  // μ—°μ‚°ν•  λ‚΄μš©
  return κ³„μ‚°λœκ°’;
}, [μ˜μ‘΄μ„±κ°’1, μ˜μ‘΄μ„±κ°’2]);

 

 

  • 첫 번째 μΈμžλŠ” 연산을 μˆ˜ν–‰ν•˜λŠ” ν•¨μˆ˜μ΄λ‹€.
  • 두 번째 인자인 μ˜μ‘΄μ„± 배열은, ν•΄λ‹Ή κ°’λ“€ 쀑 ν•˜λ‚˜λΌλ„ λ³€κ²½λ˜μ—ˆμ„ λ•Œλ§Œ 첫 번째 ν•¨μˆ˜κ°€ λ‹€μ‹œ μ‹€ν–‰λ˜λ„λ‘ ν•œλ‹€.
  • useMemoλŠ” κ³„μ‚°λœ 값을 memoizedValue에 μ €μž₯ν•˜κ³ , ν•„μš” μ‹œ 이λ₯Ό μž¬μ‚¬μš©ν•œλ‹€.

 

 

 

 

 

 

찐 μ˜ˆμ‹œλ‘œ μ½”λ“œ λ™μž‘μ„ νŒŒμ•…ν•΄λ³΄μž! 

 

ex.

Todo List μ•±μ—μ„œ μ™„λ£Œν•œ 일, μ™„λ£Œν•˜μ§€ μ•Šμ€ 일, 전체 ν•  일의 개수λ₯Ό 화면에 λ Œλ”λ§ ν•˜λŠ” μ½”λ“œμ—μ„œ useMemoλ₯Ό μ μš©μ‹œν‚¬ κ²ƒμž„.

 

const { totalCount, doneCount, notDoneCount } = useMemo(() => {
  console.log("getAnalyzedData 호좜!");
  const totalCount = todos.length;
  const doneCount = todos.filter((todo) => todo.isDone).length;
  const notDoneCount = totalCount - doneCount;

  return {
    totalCount,
    doneCount,
    notDoneCount
  };
}, [todos]);
  • todos μƒνƒœκ°€ 변경될 λ•Œμ—λ§Œ 연산을 λ‹€μ‹œ μˆ˜ν–‰ν•¨.  -> μ˜μ‘΄μ„± λ°°μ—΄
  • μ™„λ£Œλœ ν•­λͺ©κ³Ό λ―Έμ™„λ£Œ ν•­λͺ©μ˜ 개수λ₯Ό κ³„μ‚°ν•˜λŠ” λ‘œμ§μ€ filter()λ₯Ό 톡해 반볡 연산을 ν¬ν•¨ν•˜λ―€λ‘œ, μƒνƒœκ°€ 자주 변경될 경우 λΆˆν•„μš”ν•˜κ²Œ λ¦¬λ Œλ”λ§ λΉ„μš©μ΄ 증가할 수 μžˆλ‹€. (배열을 κ³„μ†ν•΄μ„œ 전체 νƒμƒ‰ν•˜κΈ° λ•Œλ¬Έ..;) 
  • 이λ₯Ό useMemo둜 감싸면, todosκ°€ λ°”λ€Œμ§€ μ•ŠλŠ” ν•œ μ΄μ „μ˜ κ³„μ‚°λœ 값을 κ·ΈλŒ€λ‘œ μž¬μ‚¬μš©ν•˜μ—¬ λ Œλ”λ§ μ„±λŠ₯을 μ΅œμ ν™”ν•  수 μžˆλ‹€.

 

 

 

 

 

 

 

 

 

근데 μƒκ°ν•΄λ³΄λ‹ˆ 전에 전에 filter()둜 검색 κΈ°λŠ₯ λ§Œλ“€μ–΄ λ†“μ•˜λ˜κ²Œ 생각났닀.

πŸ’‘κ²€μƒ‰ κΈ°λŠ₯κ³Ό useMemoλŠ” ν•¨κ»˜ 써야 ν• κΉŒ?

const getFilteredData = () => {
  if (search === "") return todos;
  return todos.filter((todo) =>
    todo.content.toLowerCase().includes(search.toLowerCase())
  );
};

const FilteredTodos = getFilteredData();

 

검색 κΈ°λŠ₯의 filter() μ—­μ‹œ useMemoλŠ” ν•¨κ»˜ μ“°λŠ”κ²Œ μ’‹μ„κΉŒ? κΆκΈˆν•΄μ„œ μ°Ύμ•„λ³΄μ•˜μŒ.

 

κ²°λ‘ :

필터링 둜직 μžμ²΄μ™€, μž…λ ₯κ°’( 검색창에 μž…λ ₯λ˜λŠ” κ°’) 이 λ³€κ²½ 될 λ•Œλ§ˆλ‹€ λ™μž‘ν•˜λŠ” κ²ƒκΉŒμ§€λŠ” μžμ—°μŠ€λŸ¬μš΄  UX νλ¦„μœΌλ‘œ λ³Ό 수 μžˆλ‹€κ³  ν•œλ‹€.

 

BUT , 

λ§Œμ•½ Todo ν•­λͺ©μ΄ 수 백개 μ΄μƒμœΌλ‘œ λŠ˜μ–΄λ‚˜λŠ” 상황이라면, 이건 더이상 λ‹¨μˆœ 검색 κΈ°λŠ₯이 μ•„λ‹ˆκΈ° λ•Œλ¬Έμ— useMemoλ₯Ό μ μš©ν•˜λŠ” 것이 μœ λ¦¬ν•΄μ§! 

 

 

 

 

search λ˜λŠ” todosκ°€ 변경될 λ•Œλ§Œ 필터링 연산을 μˆ˜ν–‰ν•˜λ„λ‘ u

seMemo둜 검색기λŠ₯을 감싸 λ³΄μ•˜λ‹€.

const filteredTodos = useMemo(() => {
  if (search === "") return todos;
  return todos.filter((todo) =>
    todo.content.toLowerCase().includes(search.toLowerCase())
  );
}, [search, todos]); 

 

μœ„μ²˜λŸΌ useMemo둜 κ°μ‹ΈλŠ” 경우,

μ˜μ‘΄μ„± 배열에 ν¬ν•¨λœ search와 todosλŠ” λ‘˜ 쀑 ν•˜λ‚˜λ§Œ λ³€κ²½λ˜μ–΄λ„ 연산이 λ‹€μ‹œ μˆ˜ν–‰λ¨.

 

search κ°€ λ°”λ€Œλ©΄ → 필터링 κΈ°μ€€(검색어)이 달라짐, μ—°μ‚° λ‹€μ‹œ μˆ˜ν–‰

todosκ°€ λ°”λ€Œλ©΄ → 필터링 λŒ€μƒ λͺ©λ‘μ΄ λ°”λ€œ, μ—°μ‚° λ‹€μ‹œ μˆ˜ν–‰

 

 

 

ν•˜μ§€λ§Œ κΈ°μ–΅ν•  건 무쑰건 useMemoλ₯Ό μ‚¬μš©ν•˜λŠ” 것이 μ•„λ‹Œ, 

μ½”λ“œ 흐름 , μ„±λŠ₯을 λ”°μ Έκ°€λ©° μ‚¬μš©ν•΄μ•Ό ν•˜λŠ” 것 ☺️

 

 

 

 

 

 


 

πŸ’‘μ •λ¦¬

 

React의 useMemo 훅은 λ‹¨μˆœνžˆ μ„±λŠ₯ μ΅œμ ν™”λ₯Ό μœ„ν•œ 도ꡬ가 μ•„λ‹ˆλΌ,

μ»΄ν¬λ„ŒνŠΈμ˜ λ™μž‘μ„ 예츑 κ°€λŠ₯ν•˜κ²Œ λ§Œλ“€κ³  λΆˆν•„μš”ν•œ λ Œλ”λ§μ„ λ°©μ§€ν•˜λŠ” μ€‘μš”ν•œ μˆ˜λ‹¨.

 

 

Q. μ–Έμ œ μ”λ‹ˆκΉŒ?

  • 반볡적인 연산이 μžˆλŠ” 경우
  • μ—°μ‚° κ²°κ³Όκ°€ λ³€ν•˜μ§€ μ•Šμ•„λ„ 자주 λ Œλ”λ§λ˜λŠ” μ»΄ν¬λ„ŒνŠΈ
  • λ¦¬μŠ€νŠΈλ‚˜ ν…Œμ΄λΈ”μ²˜λŸΌ ν•­λͺ©μ΄ λ§Žμ•„μ§ˆ 수 μžˆλŠ” ꡬ쑰

이런 μƒν™©μ—μ„œλŠ” useMemo의 λ„μž…μ΄ ν•„μˆ˜μ μ΄λ‹€.

단, λͺ¨λ“  계산에 무쑰건적으둜 μ‚¬μš©ν•˜λŠ” 것은 였히렀 μ½”λ“œ λ³΅μž‘λ„λ§Œ 높일 수 μžˆμœΌλ―€λ‘œ, μ—°μ‚° λΉ„μš©κ³Ό λΉˆλ„λ₯Ό κ³ λ €ν•˜μ—¬ μ μš©ν•˜λŠ” 것이 μ’‹λ‹€.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

*Ref

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

 

useMemo – React

The library for web and native user interfaces

ko.react.dev

μ„€λͺ…이 λΆ€μ‘±ν•œ λΆ€λΆ„μ΄λ‚˜ ν”Όλ“œλ°±μ€ λŒ“κΈ€λ‘œ λ‚¨κ²¨μ£Όμ„Έμš”!

κ°μ‚¬ν•©λ‹ˆλ‹€ ☺️

728x90