Reputation:
I currently learning react-native.
I am trying to stored a variable into asyncstrorage in scriptone.js and calling it in scripttwo.js
But i failed to stored the variable in scriptone.js
What i have import in scriptone.js:
import React, { Component, BackAndroid } from "react";
import { AsyncStorage } from 'AsyncStorage';
import { View, Text, StyleSheet, Button, Image, TouchableOpacity, TextInput, Alert} from "react-native";
This is part of my code in scriptone.js
class SettingScreen extends Component {
state = {
a: '70',
b: '',
c: '',
};
onPressButton = () => {
if (this.state.a == this.state.aa) {
this.setState({ b: this.state.a });
this.storeData();
}
else {
Alert("Try Again");
}
}
storeData(){
const {a} = this.state;
let mynum : a;
AsyncStorage.setItem('array',mynum)
Alert("Saved");
}
...
The error display :
"undefined is not an object(evaluating '_AsyncStorage.AsyncStorage.setItem')
May I know what the problem? Thank you.
Upvotes: 0
Views: 2813
Reputation: 28539
Usually to use AsyncStorage you first import it at the top of you file, the documentation says that you should import it as follows:
import { AsyncStorage } from 'react-native';
Which you can see here https://facebook.github.io/react-native/docs/asyncstorage
Obviously you should remove the previous import statement
import { AsyncStorage } from 'AsyncStorage';
as leaving it in will cause name conflicts.
Saving to AsyncStorage is an asynchronous task so you should use an async/await
function that means you should update your storeData()
function. You can see the documentation https://facebook.github.io/react-native/docs/asyncstorage for how you should do this.
storeData = async () => {
const {a} = this.state;
let mynum = a;
try {
await AsyncStorage.setItem('array', mynum)
Alert("Saved");
} catch (err) {
console.warn(err);
}
}
Next it looks like you could be getting yourself into a race condition when you're setting the state. It takes time for setState to set the item to state. So when you call
this.setState({ b: this.state.a });
the state may not have actually been set by the time you call
this.storeData();
leading to the wrong value being stored in AsyncStorage.
To over come this there is a couple of ways you could handle this
this.storeData()
This article goes into quite some detail about using setState with a callback https://medium.learnreact.com/setstate-takes-a-callback-1f71ad5d2296 however you could refactor your onPressButton
to something like this
onPressButton = () => {
if (this.state.a == this.state.aa) {
this.setState({ b: this.state.a }, async () => { await this.storeData(); });
} else {
Alert("Try Again");
}
}
This will guarantee that this.storeData()
won't be run until the state has been updated.
This requires refactoring the storeData()
function to take a parameter
storeData = async (mynum) => {
try {
await AsyncStorage.setItem('array',mynum)
Alert("Saved");
} catch (err) {
console.warn(err);
}
}
Now to use this function we have to update your onPressButton
, Notice that we pass the value that we want to store to storeData
that means we no longer have to access it from state inside storeData
onPressButton = async () => {
if (this.state.a == this.state.aa) {
this.setState({ b: this.state.a });
await this.storeData(this.state.a);
} else {
Alert("Try Again");
}
}
This is also an asynchronous task and requires an async/await
. To get the string that you stored all you have to do is pass the correct key to the retrieveData
function
retrieveData = async (key) => {
try {
const value = await AsyncStorage.getItem(key);
if (value !== null) {
// We have data!!
console.log(value);
// do something with the value
}
} catch (error) {
// Error retrieving data
}
}
Upvotes: 1