React Native / AsyncStorage

AsyncStorage

useState дахь өгөгдөл апп хаагдмагц арилдаг. Харин AsyncStorage нь утасны локал санах ойд өгөгдлийг байнга хадгалдаг — апп дахин нээхэд ч мэдээлэл хэвээр байна. Хэрэглэгчийн тохиргоо, сүүлд үзсэн хичээл, нэвтрэлтийн токен зэргийг хадгалахад ашиглана.

Суулгалт

bash
npx expo install @react-native-async-storage/async-storage

Үндсэн хэрэглээ: хадгалах, унших, устгах

AsyncStorage нь бүх функц async/await ашигладаг — утас доторх файл системтэй ажилладаг тул хугацаа зардаг.

jsx
import AsyncStorage from "@react-native-async-storage/async-storage";

// Хадгалах — зөвхөн string хадгалдаг тул JSON.stringify ашиглана
const saveUser = async (user) => {
  try {
    await AsyncStorage.setItem("user", JSON.stringify(user));
    console.log("Хадгалагдлаа");
  } catch (error) {
    console.error("Хадгалахад алдаа:", error);
  }
};

// Унших
const loadUser = async () => {
  try {
    const json = await AsyncStorage.getItem("user");
    if (json !== null) {
      return JSON.parse(json);
    }
    return null; // Өгөгдөл байхгүй
  } catch (error) {
    console.error("Уншихад алдаа:", error);
    return null;
  }
};

// Устгах
const removeUser = async () => {
  try {
    await AsyncStorage.removeItem("user");
  } catch (error) {
    console.error("Устгахад алдаа:", error);
  }
};

// Бүгдийг цэвэрлэх — болгоомжтой ашиглах!
const clearAll = async () => {
  await AsyncStorage.clear();
};

JSON.stringify ба JSON.parse хосыг заавал ашигла — AsyncStorage зөвхөн string хадгалдаг. Объект шууд дамжуулбал [object Object] болж хадгалагдана.

Бодит жишээ: харанхуй горимын тохиргоо хадгалах

jsx
import { useEffect, useState } from "react";
import { View, Text, Switch, StyleSheet } from "react-native";
import AsyncStorage from "@react-native-async-storage/async-storage";

const DARK_MODE_KEY = "settings:darkMode";

export default function SettingsScreen() {
  const [darkMode, setDarkMode] = useState(false);
  const [loaded, setLoaded] = useState(false);

  // Апп нээгдэх үед хадгалагдсан тохиргоог унших
  useEffect(() => {
    const load = async () => {
      const stored = await AsyncStorage.getItem(DARK_MODE_KEY);
      if (stored !== null) {
        setDarkMode(stored === "true");
      }
      setLoaded(true);
    };
    load();
  }, []);

  // Утга өөрчлөгдөх бүрт хадгалах
  const toggleDarkMode = async (value) => {
    setDarkMode(value);
    await AsyncStorage.setItem(DARK_MODE_KEY, String(value));
  };

  if (!loaded) return null; // Уншиж дуустал хүлээ

  return (
    <View style={[styles.container, darkMode && styles.dark]}>
      <Text style={[styles.title, darkMode && styles.titleDark]}>Тохиргоо</Text>

      <View style={[styles.row, darkMode && styles.rowDark]}>
        <Text style={[styles.label, darkMode && styles.labelDark]}>
          Харанхуй горим
        </Text>
        <Switch
          value={darkMode}
          onValueChange={toggleDarkMode}
          trackColor={{ false: "#1e293b", true: "#164e63" }}
          thumbColor={darkMode ? "#22d3ee" : "#475569"}
        />
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, padding: 20, backgroundColor: "#f8fafc" },
  dark: { backgroundColor: "#0b1120" },
  title: {
    fontSize: 22,
    fontWeight: "bold",
    color: "#1e293b",
    marginBottom: 20,
  },
  titleDark: { color: "#f1f5f9" },
  row: {
    flexDirection: "row",
    justifyContent: "space-between",
    alignItems: "center",
    backgroundColor: "#ffffff",
    padding: 16,
    borderRadius: 10,
  },
  rowDark: { backgroundColor: "#0f172a" },
  label: { fontSize: 15, color: "#334155" },
  labelDark: { color: "#f1f5f9" },
});

Custom hook болгох

AsyncStorage логикийг дахин ашиглахын тулд custom hook болгон ялгах нь кодыг цэвэр байлгадаг:

jsx
import { useState, useEffect } from "react";
import AsyncStorage from "@react-native-async-storage/async-storage";

// useStorage — хэдэн ч дэлгэцэд ашиглаж болох hook
export function useStorage(key, defaultValue) {
  const [value, setValue] = useState(defaultValue);

  useEffect(() => {
    AsyncStorage.getItem(key).then((stored) => {
      if (stored !== null) {
        try {
          setValue(JSON.parse(stored));
        } catch {
          setValue(stored);
        }
      }
    });
  }, [key]);

  const set = async (newValue) => {
    setValue(newValue);
    await AsyncStorage.setItem(key, JSON.stringify(newValue));
  };

  const remove = async () => {
    setValue(defaultValue);
    await AsyncStorage.removeItem(key);
  };

  return [value, set, remove];
}

// Хэрэглэх жишээ:
// const [username, setUsername, removeUsername] = useStorage('username', '');

Энэ hook нь useState шиг ажилладаг боловч дотроо AsyncStorage-тай холбогдсон байна — апп хаагдаж дахин нээхэд ч утга хэвээр үлдэнэ.

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

AsyncStorage-ийг сурлаа. Дараагийн хичээлд Context API — олон дэлгэцэд хэрэгтэй өгөгдлийг (нэвтрэлтийн мэдээлэл, сонгосон хэл, харанхуй горим) props дамжуулахгүйгээр хуваалцах арга.