使用 AsyncStorage 时,本机反应保持每 10 毫秒重新渲染一次视图

react native keep re-render the view every 10 ms when using AsyncStorage

我是 ReactNative 的新手。 ( 我对 Raw 很熟悉 Android)

昨天,当我使用 AsyncStorage(我认为不正确)时,我遇到了一个问题,即视图每隔 n 百万秒就会重新呈现一次。

我的代码:

import React,  { Component} from 'react';
import {Image, Platform, StyleSheet, Text, View, Button} from 'react-native'
import { AsyncStorage } from "react-native"

export default class StorageDemo extends Component{

  constructor(props){
    super(props)
    AsyncStorage.setItem("visitTimes", 100)
    this.state = {
      isLoaded: false,
      visitTimes: 0
    }
  }

  readData = async () => {
    try{
      const result = await AsyncStorage.getItem("visitTimes")
      this.setState(
        {
          visitTimes: result,
          isLoaded: true
        }
      )
      console.info("== loaded, this.state: ")
    }catch(error){
      console.error(error)
    }
  }

  render() {
    this.readData()

    if(this.state.isLoaded){
      return(
        <View>
          <Text>Loaded!  </Text>
        </View>
      )
    }else{
      return(
        <View>
          <Text>Loading... </Text>
        </View>
      )
    }

  }
}

我还打开了一个logcat window 来查看日志,我被日志震惊了:它一直在每10毫秒重新渲染一次视图。

我的环境:

代码可以在这里找到:https://github.com/sg552/react_native_lesson_demo/blob/master/screens/StorageDemo.js

我知道我的代码不正确(使用异步、等待),所以我的问题是:

如何从 AsyncStorage 读取并渲染到页面?如何更正我的代码?

非常感谢!

好的,所以问题是你在渲染器中调用你的 func this.readData(),并且该函数本身正在调用 setState ,无论何时被调用,都会改变状态,从而触发重新- 在组件上渲染。所以在这种情况下,你已经在代码中造成了一个无限循环,因为 setState 调用了 render,它又调用了 setState 并且你 运行 内存不足。

要快速解决此问题,您可以从渲染中删除函数调用,并将其添加到按钮中,这样它只会在您需要时调用。像这样:

import React,  { Component} from 'react';
import {Image, Platform, StyleSheet, Text, View, Button} from 'react-native'
import { AsyncStorage } from "react-native"

export default class StorageDemo extends Component{

  constructor(props){
    super(props)
    this.state = {
      isLoaded: false,
      visitTimes: 0
    }
  }

  readData = async () => {
    try{
      const result = await AsyncStorage.getItem("visitTimes")
      this.setState(
        {
          visitTimes: result,
          isLoaded: true
        }
      )
      console.info("== loaded, this.state: ")
    }catch(error){
      console.error(error)
    }
  }

  render() {

    if(this.state.isLoaded){
      return(
        <View>
          <Text>Loaded! {this.state.visitTimes} </Text>
          <Button 
           onPress={() =>  {
            AsyncStorage.setItem("visitTimes", "100")
            this.setState({isLoaded: false})
            }} 
           title="Set Storage Item"
           />
        </View>
      )
    }else{
      return(
        <View>
          <Button 
          onPress={this.readData}
          title="Load from async storage"></Button>
        </View>
      )
    }

  }
}

试试这个,这应该会为您提供来自 localStorage 的值!