skip to Main Content

I am new in this topic (data store in asyncStorage) I want to store my theme color in asyncStorage because when user close the app them will remain same as they selected.
I am able to change the theme on click but there were some issue on click.

I have to click twice to change theme(eq. : if there is light theme then I have to click twick like light to dark and again light then I am able to get dark theme and If there is dark theme then I have to click twice to change theme like dark to light to dark then I will get light theme

This is my Context.js file

import React, {createContext, useEffect, useState} from 'react';
import AsyncStorage from '@react-native-async-storage/async-storage';

const Context = createContext();

export const TProvider = ({children}) => {
  const [theme, setTheme] = useState('light');

  const toggleTheam = async () => {
    const DataClr = await AsyncStorage.getItem('Color');

    setTheme(theme === 'light' ? 'dark' : 'light');

    AsyncData();
  };

  const AsyncData = async () => {
    await AsyncStorage.setItem('Color', theme);
  };

  return (
    <Context.Provider value={{theme, toggleTheam, setTheme}}>
      {children}
    </Context.Provider>
  );
};

export default Context;

and this is my First.js file from where I change my theme on Press

import React, {useContext, useEffect} from 'react';
import {View, Button, Text} from 'react-native';
import Context from './Context';
import AsyncStorage from '@react-native-async-storage/async-storage';

const First = ({navigation}) => {
  const {theme, toggleTheam, setTheme} = useContext(Context);

  useEffect(async () => {
    const Data = await AsyncStorage.getItem('Color');
    if (Data) {
      setTheme(Data);
    }
  }, []);

  console.log('Theme==>', theme);

  return (
    <View
      style={{
        height: '100%',
        padding: 20,
        backgroundColor: theme === 'light' ? '#fff' : '#000',
      }}>
      <Text
        style={{
          textAlign: 'center',
          color: theme === 'light' ? '#000' : '#fff',
        }}>
        First Screen
      </Text>
      <Button title="Change Color" onPress={toggleTheam} />
      <Button
        title="Go to next Screen"
        onPress={() => {
          navigation.navigate('Second');
        }}
      />
    </View>
  );
};
export default First;


I have tried to store my theme color in Context.js file but I am not able to get that theme when I refresh the app

2

Answers


  1. Chosen as BEST ANSWER

    I have use this to solve this funcnality. and I am able to store useContext data in asyncStorage.

     const [theme, setTheme] = useState('light');
      const [clr, setCle] = useState('');
    
      useEffect(() => {
        const MainTheme = async () => {
          try {
            const storedTheme = await AsyncStorage.getItem('Color');
            if (storedTheme !== null) {
              setTheme(storedTheme);
            }
          } catch (error) {
            console.error(error);
          }
        };
    
        MainTheme();
      }, []);
    
      const toggleTheam = () => {
        setTheme(value => {
          const newTheme = value === 'light' ? 'dark' : 'light';
          SetData(newTheme);
          return newTheme;
        });
      };
    
      const SetData = async newTheme => {
        try {
          await AsyncStorage.setItem('Color', newTheme);
        } catch (error) {
          console.error(error);
        }
      };


  2. I created this example without using useContext. But you can adapt it later if it works. I think the problem is that state is asynchronous and you are saving to the async storage immediately after setting the new state.

    Please try this:

    import React, {useState, useEffect} from 'react';
    import {View, Button, Text} from 'react-native';
    import AsyncStorage from '@react-native-async-storage/async-storage';
    
    const First = ({navigation}) => {
      const Data = await AsyncStorage.getItem('Color');
      const [theme, setTheme] = useState(Data); // you may need to handle null here
    
      const toggleTheam = async () => {
         const color = await AsyncStorage.getItem('Color');
         const newColor = color === 'light' ? 'dark' : 'light'
         setTheme(newColor);
         await AsyncStorage.setItem('Color', newColor); // I think you can not use theme here because it is asynchronous and you just set it.
     
      }
      return (
        <View
          style={{
            height: '100%',
            padding: 20,
            backgroundColor: theme === 'light' ? '#fff' : '#000',
          }}>
          <Text
            style={{
              textAlign: 'center',
              color: theme === 'light' ? '#000' : '#fff',
            }}>
            First Screen
          </Text>
          <Button title="Change Color" onPress={toggleTheam} />
          <Button
            title="Go to next Screen"
            onPress={() => {
              navigation.navigate('Second');
            }}
          />
        </View>
      );
    };
    export default First;
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search