Home > OS >  React Native async storage problem. It does only load the item before
React Native async storage problem. It does only load the item before

Time:01-10

I'm programming a react native app, which calculates the average of the grades. There you can create subjects and for each subject you can add grades. For that I have difference screens. I safe it in a dictonary, which I load it into the async storage. For example: {subject 1: [grades], subject 2: [grades] }. In real life: {math: [1, 4,2], english:[5,2]}. But now I have the problem, when I add a subject, it loads the subject before and when I add then a new subject, only then it loading it.

Here is a video with the problem and the full code(it's the same video): https://www.dropbox.com/s/4yqzl22zannb9ln/reactnativeproblem.mp4?dl=0 https://drive.google.com/file/d/1Wi37lmMCgYOAFQSOMOQebCWkQSsFiPaz/view?usp=sharing

Here is the code for app.js:

    import { React, useEffect, useState } from "react";
import { StyleSheet } from "react-native";
import { NavigationContainer } from "@react-navigation/native";
import { createNativeStackNavigator } from "@react-navigation/native-stack";
import Homescreen from "./screens/Homescreen";
import NewSubject from "./screens/NewSubject";
import ShowSubject from "./screens/ShowSubject";
import AsyncStorage from "@react-native-async-storage/async-storage";

const Stack = createNativeStackNavigator();

export default function App() {
  let [dict, setDict] = useState({});

  useEffect(() => {
    loadDictionary().then(res => {
      setDict(res);
    });
  }, []);

  useEffect(() => {
    safeDictionary();
  }, [dict]);

  async function loadDictionary() {
    const value = await AsyncStorage.getItem('dict');
    try {
      if (value) {
        return JSON.parse(value);
      }
      return ({});
    } catch (error) {
      console.log("GET ERROR AT LOAD DICTONARY: ", error)
    }
  }

  async function safeDictionary() {
    try {
      await AsyncStorage.setItem("dict", JSON.stringify(dict));
    } catch (error) {
      console.log("GET ERROR AT SAFE DICTONARY:", error);
    }
  }

  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen
          name="Home"
          component={Homescreen}
          options={{ title: "Grades Calculator" }}
          initialParams={{ dict, setDict }}
        />
        <Stack.Screen name="New Subject" component={NewSubject} initialParams={{ dict, setDict }} />
        <Stack.Screen name="Subject" component={ShowSubject} initialParams={{ dict, setDict }}/>
      </Stack.Navigator>
    </NavigationContainer>
  );
}

I hope anybody can help me :)

CodePudding user response:

Passing dynamic dict value as initialParams is not recommended. Adding and displaying subjects should be handled by their respective screens.

import { React, useEffect, useState } from "react";
import { StyleSheet, View, Button, TextInput, Text } from "react-native";
import { NavigationContainer } from "@react-navigation/native";
import { createNativeStackNavigator } from "@react-navigation/native-stack";
import AsyncStorage from "@react-native-async-storage/async-storage";

const Stack = createNativeStackNavigator();

function HomeScreen(props) {
  return (
    <View>
      <Button
        title="Add Subject"
        onPress={() => props.navigation.navigate("NewSubject")}
      />
    </View>
  );
}

function NewSubject(props) {
  const [subject, setSubject] = useState("");

  async function loadDictionary() {
    const value = await AsyncStorage.getItem("dict");
    try {
      if (value) {
        return JSON.parse(value);
      }
      return [];
    } catch (error) {
      console.log("GET ERROR AT LOAD DICTONARY: ", error);
    }
  }

  async function saveDictionary() {
    if (!subject) return;
    try {
      const prev = await loadDictionary();

      const next = [...prev, subject];
      await AsyncStorage.setItem("dict", JSON.stringify(next));

      props.navigation.navigate("Subject");
    } catch (error) {
      console.log("GET ERROR AT SAFE DICTONARY:", error);
    }
  }
  return (
    <View style={{ padding: 20 }}>
      <View>
     
        <TextInput
          placeholder="Type subject..."
          style={{ padding: 5, borderWidth: 1 }}
          onChangeText={setSubject}
        />
      </View>

      <View style={{ paddingVertical: 10 }}>
        <Button title="Add Subject" onPress={saveDictionary} />
        <Button
          title="Cancel"
          onPress={() => props.navigation.goBack()}
          color="black"
        />
      </View>
    </View>
  );
}

function ShowSubject(props) {
  let [dict, setDict] = useState([]);
  async function loadDictionary() {
    const value = await AsyncStorage.getItem("dict");
    try {
      if (value) {
        return JSON.parse(value);
      }
      return {};
    } catch (error) {
      console.log("GET ERROR AT LOAD DICTONARY: ", error);
    }
  }

  useEffect(() => {
    loadDictionary().then((res) => {
      setDict(res);
    });
  }, []);

  return (
    <View>
      {dict.map((subject) => (
        <Text key={subject}> {subject} </Text>
      ))}
      <View>
        <Button
          title="Add Subject"
          onPress={() => props.navigation.navigate("NewSubject")}
        />
      </View>
    </View>
  );
}
export default function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen
          name="Home"
          component={HomeScreen}
          options={{ title: "Grades Calculator" }}
        />
        <Stack.Screen
          name="NewSubject"
          options={{ title: "New Subject" }}
          component={NewSubject}
        />
        <Stack.Screen name="Subject" component={ShowSubject} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}


Live Demo - https://snack.expo.dev/@emmbyiringiro/d25e82

  • Related