Quantcast
Channel: Active questions tagged react-native+typescript - Stack Overflow
Viewing all articles
Browse latest Browse all 6290

AsyncStorage does not save in between app reloads with expo (TS/React Native)

$
0
0

I have a context which stores the state for a theme variable in my app.Initially it is set to empty.

AppSettingsContext.tsx

import React, {createContext, useState, useEffect} from "react";import { AppSettingsContextStruct, Themes } from "../../types";import AsyncStorage from "@react-native-async-storage/async-storage";const fetchThemeFromStorage = async () => {    return AsyncStorage.getItem("THEME")    .then((value) => {        if (value === `"LIGHT"`) {            return Themes.LIGHT;        };        if (value === `"DARK"`) {            return Themes.DARK;        };        if (value === `"empty"` || "empty") {            return Themes.EMPTY;        };        })    .catch((err) => {        console.log(err);        return Themes.LIGHT;    });};const defaultVal: AppSettingsContextStruct = {    theme: Themes.EMPTY,    setTheme: () => {},}type CtxProps = {    children: JSX.Element}const AppSettingsContext = createContext(defaultVal);const AppSettingsContextProvider:React.FC<CtxProps> = (props) => {    const [theme, setTheme] = useState<Themes>(Themes.EMPTY);    useEffect(() => {        const asyncWrap = async () => {            const storageTheme = await fetchThemeFromStorage();            return {                theme: storageTheme,            }        }        asyncWrap().then((value) => {            console.log("asyncWrap ran:", value)            if (value.theme === JSON.stringify(Themes.EMPTY)) {                setTheme(Themes.LIGHT);            };        })    }, []);    useEffect(() => {        AsyncStorage.setItem("THEME", JSON.stringify(theme)).then(() => {                console.log(" > ASYNC STORAGE UPDATED THEME ->", theme)            });    },[theme]);    return (<AppSettingsContext.Provider value={{theme,setTheme}}>            {props.children}</AppSettingsContext.Provider>    )}export {AppSettingsContext, AppSettingsContextProvider}

Which wraps my entire appApp.tsx

import { NavigationContainer } from '@react-navigation/native';import RootNavigator from './navigator/RootNavigator';import {UserContextProvider} from "./components/contexts/UserContext"import {AppSettingsContextProvider} from "./components/contexts/AppSettingsContext"export default function App() {      return ( <UserContextProvider><AppSettingsContextProvider> <NavigationContainer><RootNavigator /></NavigationContainer></AppSettingsContextProvider></UserContextProvider>      );}

This is then used within a hook

useAppSettingsContext.ts

import { useContext } from "react"import { AppSettingsContext } from "../components/contexts/AppSettingsContext"export const useAppSettingsContext = () => {    const context = useContext(AppSettingsContext);    if (context === undefined) {        throw new Error("useUserContext was used outside of its Provider");    }    return context}

Then I have a component to set the value of theme:

SettingsToggleComponent.tsx

import { Ionicons, MaterialCommunityIcons } from '@expo/vector-icons';import { useEffect, useState } from 'react';import { TouchableOpacity, Text, StyleSheet, View } from "react-native"import { useAppSettingsContext } from '../../hooks/useAppSettingsContext';import { Themes } from '../../types';import AsyncStorage from '@react-native-async-storage/async-storage';type Props = {    id: string;    settingName: string;    iconName: string;    sendActionLower: Function;};const SettingsToggleComponent: React.FC<Props> = ( {id, settingName, sendActionLower} ) => {    const {        theme, setTheme    } = useAppSettingsContext();    const [isLight, setIsLight] = useState<boolean>(true);    useEffect(() => {        if (theme === Themes.LIGHT) {            setIsLight(true);        } else if (theme === Themes.DARK) {            setIsLight(false);        } else {            setIsLight(false);        }    }, [])    return (<TouchableOpacity  onPress={() => {            //changing asyncStorage will cause rerender at root? -> false            if (theme === Themes.LIGHT) {                setIsLight(false)                setTheme(Themes.DARK)            } else {                setIsLight(true)                setTheme(Themes.LIGHT)            }        }}><View style={styles.settingLayout}>            {/* Make sure that the possible names for the icons are used instead of random icon names */}<View style={styles.iconContainer}><MaterialCommunityIcons name="theme-light-dark" size={24} color="#5a5a5a" /></View><View style={styles.textContainer}><View style={styles.textContainerLayout}><Text style={styles.settingName}>{settingName}</Text><View style={styles.arrowSettingValueContainer}>                            {                                isLight?<Ionicons name="ios-sunny-sharp" size={24} color="#5A5A5A" />                                : <Ionicons name="ios-moon-sharp" size={24} color="#5A5A5A" />                            }</View></View></View></View></TouchableOpacity>    )}

When I switch the theme using the component the theme updates in AsyncStorage correctly but when i reload the app from within the terminal or by restarting the expo app, AsyncStorage no longer holds the theme that was previously set.


Viewing all articles
Browse latest Browse all 6290

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>