useMemo hook
Заримдаа component дотор маш их тооцоолол хийх шаардлага гардаг — жагсаалт шүүх, математик тооцоо хийх гэх мэт. useMemo hook нь тийм тооцооллын үр дүнг "санаж үлдэж", dependency өөрчлөгдөөгүй бол дахин тооцоолохгүй байдаг. Гүйцэтгэлийг сайжруулах маш хэрэгтэй хэрэгсэл!
Асуудлыг ойлгоцгооё
Component дахин рендерлэгдэх болгонд дотроо байгаа бүх код дахин ажилладаг. Хэрэв тооцоолол удаан бол хэрэглэгч удаашралыг мэдрэнэ:
import { useState } from "react";
function App() {
const [count, setCount] = useState(0);
const [numbers] = useState([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
// count өөрчлөгдөх бүрт энэ тооцоолол дахин ажиллана — хэрэггүй!
const total = numbers.reduce((sum, n) => {
console.log("Тооцооллож байна...");
return sum + n;
}, 0);
return (
<div>
<p>Нийлбэр: {total}</p>
<button onClick={() => setCount(count + 1)}>+1 ({count})</button>
</div>
);
}
numbers огт өөрчлөгдөхгүй ч count дарах бүрт нийлбэр дахин тооцоологдоно. Энэ нь томоохон өгөгдөлтэй бол маш удаан болдог.
useMemo ашиглах нь
import { useState, useMemo } from "react";
function App() {
const [count, setCount] = useState(0);
const [numbers] = useState([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
// numbers өөрчлөгдөхөд л дахин тооцоолно, count өөрчлөгдөхөд тооцоолохгүй
const total = useMemo(() => {
console.log("Тооцооллож байна...");
return numbers.reduce((sum, n) => sum + n, 0);
}, [numbers]); // dependency array — юу өөрчлөгдөхөд тооцоолох вэ?
return (
<div>
<p>Нийлбэр: {total}</p>
<button onClick={() => setCount(count + 1)}>+1 ({count})</button>
</div>
);
}
useMemo хоёр аргумент авдаг:
- Тооцоолол хийх функц — үр дүн буцаах ёстой
- Dependency array — ямар утга өөрчлөгдөхөд дахин тооцоолох вэ
Жагсаалт шүүх жишээ
useMemo-н хамгийн нийтлэг хэрэглээ бол жагсаалт шүүх ба эрэмбэлэх:
import { useState, useMemo } from "react";
const students = [
{ id: 1, name: "Болд", score: 85 },
{ id: 2, name: "Нараа", score: 92 },
{ id: 3, name: "Дорж", score: 78 },
{ id: 4, name: "Сарнай", score: 95 },
{ id: 5, name: "Бат", score: 88 },
];
export default function Classroom() {
const [search, setSearch] = useState("");
const [minScore, setMinScore] = useState(0);
// search эсвэл minScore өөрчлөгдөхөд л шүүнэ
const filtered = useMemo(() => {
console.log("Шүүж байна...");
return students
.filter((s) => s.name.includes(search))
.filter((s) => s.score >= minScore)
.sort((a, b) => b.score - a.score);
}, [search, minScore]);
return (
<div>
<input
value={search}
onChange={(e) => setSearch(e.target.value)}
placeholder="Нэрээр хайх"
/>
<input
type="number"
value={minScore}
onChange={(e) => setMinScore(Number(e.target.value))}
placeholder="Хамгийн бага оноо"
/>
<ul>
{filtered.map((s) => (
<li key={s.id}>
{s.name} — {s.score} оноо
</li>
))}
</ul>
</div>
);
}
useMemo хэзээ ашиглах вэ?
useMemo нь бүх газар хэрэглэх шаардлагагүй — зөвхөн үнэтэй тооцооллыг оновчлоход хэрэглэ:
// ✅ Зөв — их тооцоолол, том өгөгдөл
const sortedData = useMemo(() => expensiveSort(data), [data]);
// ✅ Зөв — React.memo-тэй хослуулах үед object props
const config = useMemo(() => ({ theme: "dark", lang: "mn" }), []);
// ❌ Хэрэггүй — энгийн тооцоолол, memo overhead нь тус биш
const double = useMemo(() => count * 2, [count]);
// Үүний оронд ингэ: const double = count * 2;
useMemo нь утга (value) буцаадаг. Харин функц санаж үлдэхийг хүвэл дараагийн хичээлд сурах useCallback хэрэглэнэ.
Дараагийн хичээлд:
useCallback hook-ийг сурна — функцийг хэрхэн санаж үлдэхийг ойлгоно. useMemo ба useCallback-н ялгааг тодорхой болгоно. React.memo-тэй хослуулан хэрэглэхэд яагаад useCallback зайлшгүй болдгийг харна.