[React] useMemo (ft. μ¬μ°μ° μ΅μ ν)
π‘μ΅μ ν
μ½ν λ₯Ό μ€λΉνλ©΄μλ, μ ν리μΌμ΄μ κ°λ°μ νλ©΄μλ νμ μ κ²½μ¨μΌνλ€κ³ λλν λ€μ μ½λ μ΅μ ν.. ! λλ₯..
리μ‘νΈ μ ν리μΌμ΄μ μ κ°λ°ν λ μμ λ§μ°¬κ°μ§μ΄λ€.
리μ‘νΈμμλ 'λ λλ§κ³Ό μ°μ°'μ΄ μ±λ₯μ ν° μν₯μ λ―ΈμΉλ€.
νΉν, μν( 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
μ€λͺ μ΄ λΆμ‘±ν λΆλΆμ΄λ νΌλλ°±μ λκΈλ‘ λ¨κ²¨μ£ΌμΈμ!
κ°μ¬ν©λλ€ βΊοΈ