javascript - React Native 问题 - 通过从构造函数调用另一个方法来初始化状态

标签 javascript reactjs react-native asyncstorage

我有一个小型的 React Native 组件,我尝试通过从本地存储(AsyncStorage)读取值来初始化状态。但是当我从构造函数调用外部方法时,我得到 未定义 作为状态值。

这是我的代码的一部分:

constructor(props) {
    super(props);
    this.state = {
       languageChecked: I18n.locale, 
       anonymityChecked: this.pickLocalKey('anonymity', true), 
       locationChecked: this.pickLocalKey('location', false),  
       notificationChecked: this.pickLocalKey('notification', false),
       statisticsChecked: this.pickLocalKey('statistics', false),
    };
    console.log("STATE: " + this.state.anonymityChecked); // UNDEFINED
}

pickLocalKey(key, defaultValue) {
  AsyncStorage.getItem(key).then((value) => {
    const item = (value !== null && value !== undefined) ? value : defaultValue;
    console.log(item);
    return item;
  });
}

有谁知道如何解决这个问题吗? 预先感谢您

最佳答案

您在问题中粘贴的代码存在几个问题。

首先,构造函数是同步的,您尝试在其中执行异步任务。这不是一个好主意。

如果您需要从 AsyncStorage 加载值并将它们存储在 state 中,您应该在 componentDidMount 中执行此操作

因此在构造函数中设置初始值,添加一个附加值loaded: false。这在以后会变得很重要。

constructor (props) {
  super(props);
  this.state = {
    languageChecked: I18n.locale,
    anonymityChecked: true,
    locationChecked: false,
    notificationChecked: false,
    statisticsChecked: false,
    loaded: false // <- add this additional value
  };
}

目前,您的 pickLocalKey 函数实际上并未返回任何内容。返回值被困在一个 promise 中。幸运的是,我们可以将函数转换为使用async/await。所以它应该看起来像这样:

pickLocalKey = async (key, defaultValue) => {
  try {
    let value = await AsyncStorage.getItem(key);
    const item = (value !== null && value !== undefined) ? value : defaultValue;
    return item === 'true'; // this will make sure we get a Boolean back as long as you store strings 'true' and 'false' for your Booleans
  } catch (error) {
    return defaultValue;
  }
}

请注意,await 可能会抛出异常,因此最好将其包装在 try/catch 中。

然后在您的 componentDidMount 中,您应该进行调用以从 AsyncStorage 检索值

async componentDidMount () {
  // these won't throw as we are catching the error before it gets here
  let anonymityChecked = await this.pickLocalKey('anonymity', true);
  let locationChecked = await this.pickLocalKey('location', false);
  let notificationChecked = await this.pickLocalKey('notification', false);
  let statisticsChecked = await this.pickLocalKey('statistics', false);
  // set all items in state in one go as multiple calls to setState are not good
  this.setState({
    anonymityChecked,
    locationChecked,
    notificationChecked,
    statisticsChecked,
    loaded: true . // <- we set loaded to true
  }, () => console.log(this.state)); // this is how you check state after it has been set
}

然后在您的 render 中,您现在应该使用 loaded 现在为 true 的事实来渲染正确的 View :

render () {
  if (this.state.loaded) {
    return (
      this is the view that you actually want to show
    )
  } else {
    return (
      this is the view that you will show when everything is loading
    )
  }
}

以下是一些值得阅读的文章:

关于javascript - React Native 问题 - 通过从构造函数调用另一个方法来初始化状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54970596/

相关文章:

ios - React Native : RNGeocoder. reverseGeocodeLocation - 可能未处理的 promise 拒绝

javascript - 无法使用 jquery 选择特定元素

javascript - 应用 CSS 后未触发鼠标事件

javascript - 如何在 React 中等待 useDispatch 值?

ios - Swift 中的 React-native iOS 桥接模块

android - 如何使用 android styles.xml 设置 react-native 选择器的样式?

javascript - 如何在我的移动网页上禁用多点触控缩放?

javascript - rails : Capturing error messages in JavaScript

javascript - ReactJS - ref 返回 "undefined"

javascript - 使用 react js 和 webpack 开发的 Web 应用程序的缓存问题