从AsyncStorage检索数据失败

时间:2019-01-20 05:52:06

标签: react-native asyncstorage

我是react-native的初学者。 我试图检索从Screen2.js中的screen1.js存储的数据,但失败了。

我都从React.native导入了两个.js的Asyncstorage

这就是我如何存储来自screenone.js的变量:

class XForwardedForMiddleware():
    def process_request(self, request):
        if request.META.has_key("HTTP_X_FORWARDED_FOR"):
            request.META["HTTP_X_PROXY_REMOTE_ADDR"] = request.META["REMOTE_ADDR"]
            parts = request.META["HTTP_X_FORWARDED_FOR"].split(",", 1)
            request.META["REMOTE_ADDR"] = parts[0]

这是我尝试在screentwo.js中检索数据的方式:

class screenone extends Component {
  state = {
      oldpin: '000000',
      newpin: '',
      secpin: '',
     };

  onPressButton = () => {
      if (this.state.newpin == this.state.secpin) {
        this.setState(
            { oldpin: this.state.newpin },
             async() => await this.storeData());
      }
       else {
        ToastAndroid.show("Password Unmatched", ToastAndroid.SHORT);
      }
    }

   storeData = async () =>{
        const {oldpin} = this.state;
        let  pin : oldpin;
        try{
            await AsyncStorage.setItem('mypin',pin);
            ToastAndroid.show("Password Changed", ToastAndroid.SHORT);
        }
        catch (err){
            console.warn(err)
        }}
....

错误:

class screentwo extends Component {
  constructor(props) {
super(props);
this.onComplete = this.onComplete.bind(this);
this.state = {
  pin: ''
};
}

retrieveData = async (mypin) => {
  try {
    let value = await AsyncStorage.getItem(mypin);
    if (value !== null) {
      console.log(value);
      this.setState({
      pin: value})
    }
   } catch (error) {
      console.warn(err)
   }
}

onComplete(inputtedPin, clear) {
  retrieveData();
  if (inputtedPin !== this.state.pin) {
    ToastAndroid.show("Incorrect Pin", ToastAndroid.SHORT);
    clear();
  } else {
    ToastAndroid.show("Pin is correct", ToastAndroid.SHORT);
    clear();
    this.props.navigation.navigate("Dashboard");
  }}
  ....

我使用正确的方法来存储和检索数据吗? 有什么建议吗?

谢谢。

3 个答案:

答案 0 :(得分:1)

当您从调用方方法调用异步方法时,该方法也将变为异步Try前缀 async onComplete(){等待this.retrieveData()}

答案 1 :(得分:1)

我的代码中有几个问题。

首先使用retrieveData()函数。它是异步的,应该用await来调用,否则会出现错误:Reference Error: ReferenceError:Can't find variable:retrieveData,因为您没有使用this

因此理想情况下,您应该将其命名为await this.retrieveData();

此功能还有其他一些问题。您使用参数mypin,但是在调用它时似乎没有将任何参数传递给该函数。要解决此问题,您应该像这样致电retreiveData()

await this.retrieveData('mypin');

或者您可以完全删除传递参数,这将在下面的重构中显示。

最后,每次您检查retreiveData时,您都会呼叫inputtedPin,效率不高,asynchronous可能要花一些时间,其次, setState函数将完成,这意味着当您根据inputtedPin检查状态时,状态可能未及时更新,这意味着您正在根据错误的值检查inputtedPin

代码重构

这就是我重构您的组件的方式。

  1. 重构retrieveData,使其不再使用参数,并且将密钥硬编码在.getItem
  2. componentDidMount中,从AsyncStorage获取引脚的值并将其保存到状态。
  3. retrieveData删除onComplete呼叫

这是重构

retrieveData = async () => { // parameter have been removed
  try {
    let value = await AsyncStorage.getItem('mypin'); // notice I am now passing the key as a string not as a parameter
    if (value !== null) {
      console.log(value);
      this.setState({ pin: value })
    }
   } catch (error) {
      console.warn(err)
   }
}

// here we call the refactored retrievedData which will set the state. 
async componentDidMount () {
  await this.retrieveData();
}

onComplete(inputtedPin, clear) {
  // we remove the call to retrieveData as we have already gotten the pin in the componentDidMount
  if (inputtedPin !== this.state.pin) {
    ToastAndroid.show("Incorrect Pin", ToastAndroid.SHORT);
    clear();
  } else {
    ToastAndroid.show("Pin is correct", ToastAndroid.SHORT);
    clear();
    this.props.navigation.navigate("Dashboard");
  }
}

答案 2 :(得分:0)

仅替换

retrieveData();

this.retrieveData();