AsyncStorage.setItem在iOS上崩溃,但在Android上完美运行,Expo。

3

这是我正在导入的内容:

import React, { Component } from 'react'
import {
  Image,
  Text,
  TextInput,
  Keyboard,
  KeyboardAvoidingView,
  TouchableOpacity,
  View,
  Linking,
  AsyncStorage,
  Alert
} from 'react-native'

以下是设置状态的函数(从下面的TextInput调用)

setName = (name, value) => {
    AsyncStorage.setItem(name, value);
}

这是它的调用方式:

<TextInput
    keyboardType='default'
    autoCapitalize='words'
    returnKeyType='next'
    onSubmitEditing={() => this.lastNamedRef.focus()}
    underlineColorAndroid='transparent'
    style={{flex:1}}
    placeholder='Your first name'
    value={this.state.firstName}
    onChangeText={(text) => [this.validateInputLength(text, 2, 50, 'firstName'), this.setName('firstName', this.state.firstName)]}
 />

<TextInput
    keyboardType='default'
    autoCapitalize='words'
    returnKeyType='done'
    ref={lastNameRef => this.lastNamedRef = lastNameRef}
    underlineColorAndroid='transparent'
    style={{flex:1}}
    placeholder='Your last name'
    value={this.state.lastName}
    onChangeText={(text) => [this.validateInputLength(text, 2, 50, 'lastName'), this.setName('lastName', this.state.lastName)]}
 />

如果我从TextInput的onChangeText中删除this.setName()函数,该应用程序不会崩溃,但是当它存在时,在iOS上它会崩溃,但在Android上不会。当componentWillMount()被更新时,this.state.firstName和this.state.lastName来自AsyncStorage,并使用setName函数(上面)进行更新。
componentWillMount() {
    AsyncStorage.getItem('firstName').then((value) => this.setState({firstName:value}))
    AsyncStorage.getItem('lastName').then((value) => this.setState({lastName:value}))
}

componentWillMount()中的AsyncStorage.getItem不会导致应用程序崩溃,但似乎无法一致地将数据加载到字段中。大多数情况下它可以加载,但并非每次都能成功。总体而言,AsyncStorage似乎存在很多bug。

以下是validateInputLength函数:

validateInputLength = (text, min=10, max=25, type) => {
  if(text.length < min || text.length > max) {
    if(type=='firstName') {
      this.setState({firstName:text})
      this.setState({firstNameValidated:false})
      return false;
    } else if (type=='lastName') {
      this.setState({lastName:text})
      this.setState({lastNameValidated:false})
      return false;
    }
  } else {
    if(type=='firstName') {
      this.setState({firstName:text})
      this.setState({firstNameValidated:true})
    } else if (type=='lastName') {
      this.setState({lastName:text})
      this.setState({lastNameValidated:true})
    }
  }
}

...这里是构造函数

constructor(props) {
  super(props)
  this.state = {
    firstName: '',
    lastName: '',
    firstNameValidated: false,
    lastNameValidated: false,
  };
}

这会导致 expo 在 iOS 上崩溃,无论是在我的 iPhone 上还是在模拟器中运行,不会显示任何错误。有什么想法吗?


你能展示一下 validateInputLength 函数吗? - Harsh Vardhan
1个回答

15

如果你尝试将一个JSON对象存入 AsyncStorage,那么只能存储字符串。否则,例如 expo 会崩溃,这可能就是问题所在。请在存储对象之前使用 JSON.stringify 进行转换。


2
我曾经存储了JSON.stringify(myObject)而不是myObject,这起作用了!谢谢! - Greg A
只能存储字符串,注意不能存储其他的数据类型,如 undefined、null、数字等。如果尝试这样做,会导致 AsyncStorage 崩溃。 - drazewski
在我的情况下,该值是一个数字。value.toString() 可以工作。await AsyncStorage.setItem('@key', value.toString())。如果该值是一个字符串,则 toString 会被简单地忽略。我已经在 AsyncStorage 的 GitHub 上报告了这个问题。 - Scott Daniel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接