React Native / Context API React Native-д

Context API React Native-д

Олон дэлгэцэд нэгэн зэрэг хэрэгтэй өгөгдөл — жишээ нь нэвтрэлтийн мэдээлэл, харанхуй горим, хэрэглэгчийн XP — -ийг props-оор давхарласан дамжуулах нь уйтгартай болдог. Context API нь энэ асуудлыг шийдэж дурын component-д глобал өгөгдлийг шууд хүргэдэг. React Native-д яг React-н нэгэн адил ажилладаг.

Context үүсгэх

jsx
// context/AuthContext.jsx
import { createContext, useContext, useState } from "react";

// 1. Context үүсгэнэ
const AuthContext = createContext(null);

// 2. Provider component — бүх дэлгэцийг ороодог
export function AuthProvider({ children }) {
  const [user, setUser] = useState(null);

  const login = (userData) => setUser(userData);
  const logout = () => setUser(null);

  return (
    <AuthContext.Provider value={{ user, login, logout }}>
      {children}
    </AuthContext.Provider>
  );
}

// 3. Custom hook — дуудахад хялбар болгоно
export function useAuth() {
  const ctx = useContext(AuthContext);
  if (!ctx) throw new Error("useAuth нь AuthProvider дотор байх ёстой");
  return ctx;
}

Provider-г аппд холбох

Context нь ашиглах бүх дэлгэцийг хамрах хэрэгтэй — ихэвчлэн App.jsx дотор хамгийн гадна давхарт байршуулна:

jsx
// App.jsx
import { NavigationContainer } from "@react-navigation/native";
import { AuthProvider } from "./context/AuthContext";
import RootNavigator from "./navigation/RootNavigator";

export default function App() {
  return (
    <AuthProvider>
      <NavigationContainer>
        <RootNavigator />
      </NavigationContainer>
    </AuthProvider>
  );
}

Provider-г NavigationContainer-н гадна байршуулсанд анхаарна уу — ингэснээр навигацийн бүх дэлгэц context-д хандах боломжтой болно.

Context-г дэлгэцүүдэд ашиглах

jsx
// screens/HomeScreen.jsx
import { View, Text, TouchableOpacity, StyleSheet } from "react-native";
import { useAuth } from "../context/AuthContext";

export default function HomeScreen({ navigation }) {
  const { user, logout } = useAuth();

  return (
    <View style={styles.container}>
      <Text style={styles.greeting}>
        Сайн байна уу, {user?.username ?? "зочин"}!
      </Text>
      <Text style={styles.xp}>XP: {user?.xp ?? 0}</Text>

      <TouchableOpacity
        style={styles.logoutBtn}
        onPress={() => {
          logout();
          navigation.replace("Login");
        }}
      >
        <Text style={styles.logoutText}>Гарах</Text>
      </TouchableOpacity>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    padding: 24,
    backgroundColor: "#0b1120",
  },
  greeting: {
    fontSize: 24,
    fontWeight: "bold",
    color: "#f1f5f9",
    marginBottom: 8,
  },
  xp: { fontSize: 16, color: "#22d3ee", marginBottom: 32 },
  logoutBtn: {
    backgroundColor: "#1e293b",
    padding: 14,
    borderRadius: 10,
    alignItems: "center",
  },
  logoutText: { color: "#94a3b8", fontSize: 15 },
});
jsx
// screens/LoginScreen.jsx
import {
  View,
  Text,
  TextInput,
  TouchableOpacity,
  StyleSheet,
} from "react-native";
import { useState } from "react";
import { useAuth } from "../context/AuthContext";

export default function LoginScreen({ navigation }) {
  const { login } = useAuth();
  const [email, setEmail] = useState("");

  const handleLogin = () => {
    login({ username: "Болд", email, xp: 120 });
    navigation.replace("Home");
  };

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Нэвтрэх</Text>
      <TextInput
        style={styles.input}
        value={email}
        onChangeText={setEmail}
        placeholder="И-мэйл"
        placeholderTextColor="#475569"
        keyboardType="email-address"
        autoCapitalize="none"
      />
      <TouchableOpacity style={styles.btn} onPress={handleLogin}>
        <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",
  },
  btnText: { color: "#0b1120", fontWeight: "bold", fontSize: 16 },
});

Олон context хослуулах

Апп томрох тусам context тусдаа хариуцлагатай байх нь зөв — auth, theme, өгөгдлийн cache тус бүрдээ Context байж болно:

jsx
// Олон Provider давхарлах
export default function App() {
  return (
    <AuthProvider>
      <ThemeProvider>
        <NavigationContainer>
          <RootNavigator />
        </NavigationContainer>
      </ThemeProvider>
    </AuthProvider>
  );
}

Context нь хялбар глобал state-д тохиромжтой. Гэхдээ өгөгдлийн шинэчлэлт ойр ойрхон байх (жишээ нь тоолуур) эсвэл маш олон component шинэчлэгдэх тохиолдолд дараагийн хичээлд үзэх Zustand илүү тохиромжтой.

Дараагийн хичээлд:

Context API-г сурлаа. Дараагийн хичээлд Zustand — Context-ээс хялбар бичигдэж, гүйцэтгэл сайтай state менежментийн сан. Том аппд Context-н оронд ашиглах нь улам түгэмжилж байна.