реагирует на родной, повторный рендеринг вида каждые 10 мс при использовании AsyncStorage - PullRequest
0 голосов
/ 25 декабря 2018

Я новичок в 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, чтобы проверить журнал, я был шокирован журналом: он продолжал повторять рендеринг View каждые 10 мс.

enter image description here

Моя среда:

  • Android SDK: 27
  • Windows
  • 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 и отображать его на странице?Как исправить мой код?

спасибо большое!

1 Ответ

0 голосов
/ 25 декабря 2018

Хорошо, проблема в том, что вы вызываете свой 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!

...