Zustand React Native-д
Zustand бол маш хялбар, боловч хүчирхэг state менежментийн сан. Context API-тай харьцуулбал бичих код хамаагүй бага, гүйцэтгэл сайн, Provider дотор ороодог хэрэггүй. React Native-д Context-н оронд Zustand ашиглах нь улам түгэмжилж байна.
Суулгалт
npm install zustand
Анхны store үүсгэх
Zustand-д create() функцээр store үүсгэнэ. Store нь state болон тэр state-г өөрчлөх функцуудыг хамт агуулдаг:
// store/useCounterStore.js
import { create } from "zustand";
const useCounterStore = create((set) => ({
// State
count: 0,
// Actions
increment: () => set((state) => ({ count: state.count + 1 })),
decrement: () => set((state) => ({ count: Math.max(0, state.count - 1) })),
reset: () => set({ count: 0 }),
}));
export default useCounterStore;
set функц state-г шинэчилдэг. Өмнөх state-д тулгуурлах үед set((state) => ...) функц хэлбэрийг ашиглана.
Component-д ашиглах
Provider шаардлагагүй — store-г шууд import хийгээд hook шиг дуудана:
import { View, Text, TouchableOpacity, StyleSheet } from "react-native";
import useCounterStore from "../store/useCounterStore";
export default function CounterScreen() {
const { count, increment, decrement, reset } = useCounterStore();
return (
<View style={styles.container}>
<Text style={styles.count}>{count}</Text>
<View style={styles.row}>
<TouchableOpacity
style={[styles.btn, styles.secondary]}
onPress={decrement}
>
<Text style={styles.btnText}>−</Text>
</TouchableOpacity>
<TouchableOpacity
style={[styles.btn, styles.primary]}
onPress={increment}
>
<Text style={styles.btnText}>+</Text>
</TouchableOpacity>
</View>
<TouchableOpacity onPress={reset}>
<Text style={styles.reset}>Дахин тохируулах</Text>
</TouchableOpacity>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#0b1120",
gap: 20,
},
count: { fontSize: 72, fontWeight: "bold", color: "#22d3ee" },
row: { flexDirection: "row", gap: 16 },
btn: {
width: 60,
height: 60,
borderRadius: 30,
justifyContent: "center",
alignItems: "center",
},
primary: { backgroundColor: "#22d3ee" },
secondary: { backgroundColor: "#1e293b" },
btnText: { fontSize: 28, color: "#0b1120", fontWeight: "bold" },
reset: { fontSize: 14, color: "#334155" },
});
Өөр дэлгэцэд ч useCounterStore() дуудахад ижил count утга харагдана — store нь глобал.
Бодит жишээ: хэрэглэгчийн XP store
// store/useUserStore.js
import { create } from "zustand";
const useUserStore = create((set, get) => ({
user: null,
completedLessons: [],
setUser: (userData) => set({ user: userData }),
logout: () => set({ user: null, completedLessons: [] }),
completeLesson: (slug) => {
const { completedLessons, user } = get();
if (completedLessons.includes(slug)) return; // Давтаж нэмэхгүй
set({
completedLessons: [...completedLessons, slug],
user: user ? { ...user, xp: user.xp + 10 } : user,
});
},
isCompleted: (slug) => get().completedLessons.includes(slug),
}));
export default useUserStore;
get() нь store-н одоогийн утгыг action дотроос унших боломж олгодог — set нь зөвхөн бичихэд, get нь зөвхөн уншихад ашиглана.
// screens/LessonScreen.jsx
import { View, Text, TouchableOpacity, StyleSheet } from "react-native";
import useUserStore from "../store/useUserStore";
export default function LessonScreen({ route }) {
const { slug, title } = route.params;
const { user, completeLesson, isCompleted } = useUserStore();
const done = isCompleted(slug);
return (
<View style={styles.container}>
<Text style={styles.title}>{title}</Text>
<Text style={styles.xp}>Таны XP: {user?.xp ?? 0}</Text>
<TouchableOpacity
style={[styles.btn, done && styles.btnDone]}
onPress={() => completeLesson(slug)}
disabled={done}
>
<Text style={styles.btnText}>
{done ? "✓ Дууссан — +10 XP" : "Дуусгах"}
</Text>
</TouchableOpacity>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
padding: 24,
backgroundColor: "#0b1120",
},
title: {
fontSize: 22,
fontWeight: "bold",
color: "#f1f5f9",
marginBottom: 8,
},
xp: { fontSize: 15, color: "#22d3ee", marginBottom: 32 },
btn: {
backgroundColor: "#22d3ee",
padding: 14,
borderRadius: 10,
alignItems: "center",
},
btnDone: { backgroundColor: "#1e293b" },
btnText: { color: "#0b1120", fontWeight: "bold", fontSize: 15 },
});
Context API ба Zustand харьцуулбал
| | Context API | Zustand |
| ----------- | ------------------- | ----------------------------- |
| Суулгалт | Суулгахгүй | npm install zustand |
| Provider | Шаардлагатай | Шаардлагагүй |
| Бичих код | Арай их | Маш бага |
| Гүйцэтгэл | Дундаж | Өндөр |
| Хэрэглэх үе | Энгийн глобал state | Том апп, ойр ойрхон шинэчлэлт |
Дараагийн хичээлд:
Zustand store бүтээж сурлаа. Дараагийн хичээлд Fetch API ба өгөгдөл татах — серверээс жинхэнэ өгөгдөл татах, loading/error төлөвүүдийг зохистой удирдах бүрэн загварыг судална.