useState React Native-д
React курст useState-г сурсан байгаа — React Native-д яг адилхан ажилладаг. Ялгаа нь зөвхөн <div> биш <View>, <button> биш <TouchableOpacity> ашиглах явдал. Энэ хичээлд мобайл UI-д хамгийн их тохиолддог useState загваруудыг нэгтгэн давтана.
Counter — үндсэн useState
import { View, Text, TouchableOpacity, StyleSheet } from "react-native";
import { useState } from "react";
export default function Counter() {
const [count, setCount] = useState(0);
return (
<View style={styles.container}>
<Text style={styles.count}>{count}</Text>
<Text style={styles.label}>XP</Text>
<View style={styles.row}>
<TouchableOpacity
style={[styles.btn, styles.minus]}
onPress={() => setCount((c) => Math.max(0, c - 1))}
>
<Text style={styles.btnText}>−</Text>
</TouchableOpacity>
<TouchableOpacity
style={[styles.btn, styles.plus]}
onPress={() => setCount((c) => c + 1)}
>
<Text style={styles.btnText}>+</Text>
</TouchableOpacity>
</View>
<TouchableOpacity onPress={() => setCount(0)}>
<Text style={styles.reset}>Дахин тохируулах</Text>
</TouchableOpacity>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#0b1120",
gap: 12,
},
count: { fontSize: 72, fontWeight: "bold", color: "#22d3ee" },
label: { fontSize: 16, color: "#475569", marginTop: -8 },
row: { flexDirection: "row", gap: 16, marginTop: 8 },
btn: {
width: 56,
height: 56,
borderRadius: 28,
justifyContent: "center",
alignItems: "center",
},
minus: { backgroundColor: "#1e293b" },
plus: { backgroundColor: "#22d3ee" },
btnText: { fontSize: 24, color: "#f1f5f9", fontWeight: "bold" },
reset: { fontSize: 14, color: "#334155", marginTop: 8 },
});
setCount((c) => c + 1) — функц хэлбэрийн шинэчлэлт нь өмнөх утгад тулгуурлан тооцоход найдвартай. Ялангуяа товчийг хурдан дарахад алдаа гарахаас сэргийлдэг.
Toggle — нэмэх/хасах төлөв
import { View, Text, Switch, TouchableOpacity, StyleSheet } from "react-native";
import { useState } from "react";
export default function ToggleList() {
const [darkMode, setDarkMode] = useState(true);
const [notifications, setNotifications] = useState(false);
const [expanded, setExpanded] = useState(false);
return (
<View style={[styles.container, !darkMode && styles.lightBg]}>
{/* Switch toggle */}
<View style={styles.row}>
<Text style={styles.label}>Харанхуй горим</Text>
<Switch
value={darkMode}
onValueChange={setDarkMode}
trackColor={{ false: "#1e293b", true: "#164e63" }}
thumbColor={darkMode ? "#22d3ee" : "#475569"}
/>
</View>
<View style={styles.row}>
<Text style={styles.label}>Мэдэгдэл</Text>
<Switch
value={notifications}
onValueChange={setNotifications}
trackColor={{ false: "#1e293b", true: "#164e63" }}
thumbColor={notifications ? "#22d3ee" : "#475569"}
/>
</View>
{/* Accordion toggle */}
<TouchableOpacity
style={styles.accordion}
onPress={() => setExpanded((e) => !e)}
>
<Text style={styles.label}>Дэлгэрэнгүй мэдээлэл</Text>
<Text style={styles.chevron}>{expanded ? "∧" : "∨"}</Text>
</TouchableOpacity>
{expanded && (
<View style={styles.panel}>
<Text style={styles.panelText}>
Энэ хэсэг accordion дарахад нээгдэж, дахин дарахад хаагдана.
</Text>
</View>
)}
</View>
);
}
const styles = StyleSheet.create({
container: { flex: 1, padding: 20, backgroundColor: "#0b1120" },
lightBg: { backgroundColor: "#f8fafc" },
row: {
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
backgroundColor: "#0f172a",
padding: 16,
borderRadius: 10,
marginBottom: 10,
},
label: { fontSize: 15, color: "#f1f5f9" },
chevron: { fontSize: 14, color: "#475569" },
accordion: {
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
backgroundColor: "#0f172a",
padding: 16,
borderRadius: 10,
},
panel: {
backgroundColor: "#1e293b",
padding: 16,
borderRadius: 10,
marginTop: 2,
},
panelText: { color: "#94a3b8", fontSize: 14, lineHeight: 22 },
});
Олон state нэг объектод хадгалах
Маягтны талбаруудын утгыг тус тусдаа useState -ээр хадгалах боломжтой. Гэхдээ хамааралтай өгөгдлийг нэг объектод нэгтгэх нь код уншихад ойлгомжтой болгодог:
import {
View,
Text,
TextInput,
TouchableOpacity,
StyleSheet,
} from "react-native";
import { useState } from "react";
export default function RegisterForm() {
const [form, setForm] = useState({
username: "",
email: "",
password: "",
});
// Нэг функцээр аль ч талбарыг шинэчилнэ
const update = (field, value) =>
setForm((prev) => ({ ...prev, [field]: value }));
const isValid =
form.username.length > 2 &&
form.email.includes("@") &&
form.password.length >= 6;
return (
<View style={styles.container}>
<Text style={styles.title}>Бүртгүүлэх</Text>
<TextInput
style={styles.input}
value={form.username}
onChangeText={(v) => update("username", v)}
placeholder="Хэрэглэгчийн нэр"
placeholderTextColor="#475569"
/>
<TextInput
style={styles.input}
value={form.email}
onChangeText={(v) => update("email", v)}
placeholder="И-мэйл"
placeholderTextColor="#475569"
keyboardType="email-address"
autoCapitalize="none"
/>
<TextInput
style={styles.input}
value={form.password}
onChangeText={(v) => update("password", v)}
placeholder="Нууц үг (6+ тэмдэгт)"
placeholderTextColor="#475569"
secureTextEntry
/>
<TouchableOpacity
style={[styles.btn, !isValid && styles.btnDisabled]}
disabled={!isValid}
>
<Text style={styles.btnText}>Бүртгүүлэх</Text>
</TouchableOpacity>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
padding: 24,
backgroundColor: "#0b1120",
},
title: {
fontSize: 26,
fontWeight: "bold",
color: "#f1f5f9",
marginBottom: 24,
},
input: {
backgroundColor: "#0f172a",
borderWidth: 1,
borderColor: "#1e293b",
borderRadius: 8,
padding: 13,
color: "#f1f5f9",
fontSize: 15,
marginBottom: 12,
},
btn: {
backgroundColor: "#22d3ee",
padding: 14,
borderRadius: 10,
alignItems: "center",
marginTop: 8,
},
btnDisabled: { opacity: 0.4 },
btnText: { color: "#0b1120", fontWeight: "bold", fontSize: 16 },
});
{ ...prev, [field]: value } нь spread оператор ашиглан өмнөх бүх талбарыг хадгалж зөвхөн тодорхой нэгийг нь шинэчилдэг. isValid нь бүх талбарын утгыг шалгаж товчийг идэвхтэй эсэхийг тодорхойлно.
Дараагийн хичээлд:
useState-ийн мобайл загваруудыг нэгтгэн давтлаа. Дараагийн хичээлд useEffect React Native-д — апп нээгдэх үед өгөгдөл татах, дэлгэц өөрчлөгдөхөд ажиллах side effect-үүдийг удирдана.