【问题标题】:react native keep re-render the view every 10 ms when using AsyncStorage使用 AsyncStorage 时,本机反应每 10 毫秒重新渲染一次视图
【发布时间】:2018-12-25 02:02:49
【问题描述】:

我是 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 窗口查看日志,我被日志震惊了:它每 10 毫秒就不断地重新渲染视图。

我的环境:

  • Android SDK:27
  • 窗户
  • ReactNative 0.55
  • 设备:VIVO Y67A(Android 6.0,4G RAM)

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

我知道我的代码不正确(使用 async,await),所以我的问题是:

如何读取 AsyncStorage 并将其呈现到页面?如何更正我的代码?

非常感谢!

【问题讨论】:

  • 伙计,看看 React 的生命周期,比如 componentWillMount() 并使用它。请不要在 render() 函数中计算任何内容

标签: android react-native mobile asyncstorage


【解决方案1】:

好的,所以问题是您在渲染中调用了您的函数this.readData(),而该函数本身正在调用setState,无论何时调用它都会更改状态,从而触发组件的重新渲染。因此,在这种情况下,您在代码中造成了无限循环,因为setState 调用了render,而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 的价值!

【讨论】:

  • 谢谢,非常清楚“状态改变”和“渲染”之间的关系,这解释了我为什么要面对无限循环渲染。
  • 很高兴能为您提供帮助?
猜你喜欢
  • 2023-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-15
  • 1970-01-01
相关资源
最近更新 更多