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

Having trouble persisting value in asyncstorage React Native (Typescript)

$
0
0

I am making a button in React Native which should allow the user to change between a light and dark theme:

I have wrapped my app in a context:AppSettingsContext.tsx

import {fetchThemeFromStorage} from "../../helpers/_appLoadFetch";import React, {createContext, useState, useEffect} from "react";import { AppSettingsContextStruct, Currencies, Themes } from "../../types";const defaultVal: AppSettingsContextStruct = {    theme: Themes.LIGHT,    setTheme: () => {},}type CtxProps = {    children: JSX.Element}const AppSettingsContext = createContext(defaultVal);const AppSettingsContextProvider:React.FC<CtxProps> = (props) => {    const [theme, setTheme] = useState<Themes>(Themes.LIGHT);    let storageTheme = fetchThemeFromStorage();    useEffect(()=>{        const asyncWrap = async () => {            return await storageTheme;        };        asyncWrap().then((val) => {            setTheme(val);        })    },[storageTheme])    return (<AppSettingsContext.Provider value={{theme,setTheme,currency,setCurrency,notifications,setNotifications}}>            {props.children}</AppSettingsContext.Provider>    )}export {AppSettingsContext, AppSettingsContextProvider}

Which imports the following function:_appLoadFetch.ts

export const fetchThemeFromStorage = async () => {    return AsyncStorage.getItem("THEME")    .then((value) => {        if ( value === null ) {            return Themes.LIGHT        }         return value === `"LIGHT"` ? Themes.LIGHT : Themes.DARK;        })    .catch((err) => {        console.log(err);        return Themes.LIGHT;    });};

I then have my button which should allow the user to change the theme:ChangeTheme.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';const getIsLight = async (theme: Themes) => {    if (theme === Themes.LIGHT) {        return true    }     if (theme === Themes.DARK) {        return false    }    console.log("error")    return false;} const SettingsToggleComponent = () => {    const {        theme, setTheme    } = useAppSettingsContext();    const [isLight, setIsLight] = useState<boolean>(true);    let isLightInitial = getIsLight(theme);     useEffect(() => {        const asyncWrap = async () => {            return await isLightInitial;        };        asyncWrap().then((val) => {            setIsLight(val);        })    }, [isLightInitial])    return (<TouchableOpacity  onPress={() => {            if (theme === Themes.LIGHT) {                AsyncStorage.setItem("THEME", JSON.stringify(Themes.DARK))                setTheme(Themes.DARK)                setIsLight(false)            } else {                AsyncStorage.setItem("THEME", JSON.stringify(Themes.LIGHT))                setTheme(Themes.LIGHT)                setIsLight(true)            }        }}><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>    )}

This will change the theme but when I refresh the app (using expo), it seems to rerun the fetchThemeFromStorage function a few times, resetting the theme back to Themes.LIGHT in the process as it looks like AppSettingsContextProvider is re-rendered 4 times after reloading.

I'm relatively new to React/React Native so I don't really know why this would happen.

EDIT:

The multiple re-renders only happen when I change the theme to Themes.DARK, if it is Themes.LIGHT when I reload the component will not re-render after the initial render, which is the behaviour I expect.


Viewing all articles
Browse latest Browse all 6290

Trending Articles



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