如果我使用异步存储,当我更改屏幕时,我的值怎么会重置为 0?

Posted

技术标签:

【中文标题】如果我使用异步存储,当我更改屏幕时,我的值怎么会重置为 0?【英文标题】:How come my value gets reset to 0 when I change screen if I am using async storage? 【发布时间】:2020-07-23 15:24:49 【问题描述】:

我正在使用堆栈导航器,我的主屏幕是 tracker.js,第二个屏幕是 macros.js 在 macros.js 上,我可以手动添加营养宏(卡路里、脂肪、碳水化合物、蛋白质),并将其添加到我的 UsedDailyCalories。但是,当我返回我的 tracker.js(它自动获得 0 卡路里)并返回到 macros.js 时,该值又回落到 0。而且我不确定为什么异步存储不起作用。这是我的代码:

import React from "react";
import 
  StyleSheet,
  View,
  Button,
  Text,
  TextInput,
  Modal,
  Animated,
 from "react-native";
import  TouchableOpacity  from "react-native-gesture-handler";
import AsyncStorage from "@react-native-community/async-storage";
import useDispatch from "react-redux";

export default class Macros extends React.Component 
  static navigationOptions = 
    title: "My Macros",
  ;

  constructor(props) 
    super(props);
    this.getData();


    this.state = 
      isLoading: true,
      dataSource: null,
      totalCalsSet: 0,
      showModal: false,
      showModal2: false,
      UsedDailyCalories: 0,
      UsedDailyFat: +this.props.navigation.getParam("totalFat", "nothing sent"),
      UsedDailyCarbs: 0,
      UsedDailyProtein: 0,
      CalsFatInput: 0,
      CalsProteinInput: 0,
      CalsCarbsInput: 0,
      CaloriePercentage: 0,
    ;

    let calsTakenFromTracker = this.props.navigation.getParam("totalCal", "nothing sent");
    this.state.UsedDailyCalories += calsTakenFromTracker;

  



  setMacroGoalModal = () => 
    this.setState(
      showModal: true,
    );
  ;

  AddMacrosModal = () => 
    this.setState(
      showModal2: true,
    );
  ;

  addMacrosManually = (ProteinInput, FatInput, CarbsInput) => 

    let CalsProteinInput = ProteinInput * 4;
    let CalsFatInput = FatInput * 9;
    let CalsCarbsInput = CarbsInput * 4;

    let CalsCalorieInput = CalsCarbsInput + CalsFatInput + CalsProteinInput;
    let withAddedCalories = this.state.UsedDailyCalories + CalsCalorieInput;
    this.setState(
      UsedDailyCalories :withAddedCalories,
      UsedDailyFat: +FatInput,
      UsedDailyCarbs: +CarbsInput,
      UsedDailyProtein: +ProteinInput,
      showModal2: false,
    );
    console.log(this.state.UsedDailyCalories);


    const firstPair = ["UsedTotalCalories", JSON.stringify(this.state.UsedDailyCalories)];
    const secondPair = ["UsedTotalCarbs", JSON.stringify(this.state.UsedDailyCarbs)];
    const thirdPair = ["UsedTotalProtein", JSON.stringify(this.state.UsedDailyProtein)];
    const fourthPair = ["UsedTotalFat", JSON.stringify(this.state.UsedDailyFat)];

    try 
      this.setState();
      var usedValues = [firstPair, secondPair, thirdPair, fourthPair];
      AsyncStorage.setItem("DATA_KEY", JSON.stringify(usedValues))


     catch (error) 
      console.log(error);
    

  ;

  setMacros = async (ProteinInput, FatInput, CarbsInput) => 
    let CalsProteinInput = ProteinInput * 4;
    let CalsFatInput = FatInput * 9;
    let CalsCarbsInput = CarbsInput * 4;
    let totalCalsSet = CalsCarbsInput + CalsFatInput + CalsProteinInput;

    let CaloriePercentage = (totalCalsSet / 2400) * 100;
    this.setState(
      totalCalsSet: totalCalsSet,
      CalsProteinInput: ProteinInput,
      CalsFatInput: FatInput,
      CalsCarbsInput: CalsCarbsInput,
      showModal: false,
      CaloriePercentage: CaloriePercentage,
    );
    console.log(totalCalsSet);


    const firstPair = ["totalCalsSet", JSON.stringify(this.state.totalCalories)];
    const secondPair = ["totalCarbsSet", JSON.stringify(CarbsInput)];
    const thirdPair = ["totalProteinSet", JSON.stringify(ProteinInput)];
    const fourthPair = ["totalFatSet", JSON.stringify(FatInput)];

    try 
      this.setState();
      var setValues = [firstPair, secondPair, thirdPair, fourthPair];
      AsyncStorage.setItem("DATA_KEY", JSON.stringify(setValues))


     catch (error) 
      console.log(error);
    

  ;



  getData = async () => 

    try 
      AsyncStorage.multiGet(["key1", "key2"]).then(response => 
      )

     catch(e) 
      // read error
    
  ;




  render() 


    const  navigate  = this.props.navigation;
    let CaloriePercentage = this.state.CaloriePercentage + "%";

    return (
      //styling for navigation container
      <View style=styles.container>
        <View style=styles.topStyle>
          <Text>this.state.UsedDailyCalories </Text>
          <Text>this.state.UsedDailyCarbs </Text>

          <View style=styles.setMacros>
            <TouchableOpacity onPress=() => this.setMacroGoalModal()>
              <Text> Set Daily Macro Goal </Text>
            </TouchableOpacity>
          </View>
          <View>
            <TouchableOpacity  style=styles.setMacros onPress=() => this.AddMacrosModal()>
            <Text> add Daily Macro Goal </Text>
          </TouchableOpacity>
          </View>

          <View style=styles.viewOfMacros>
            <Text>Cals: this.state.totalCalsSet</Text>
            <Text>Math.floor(this.state.CaloriePercentage)%</Text>

            <View style=styles.progressBar>
              <Animated.View
                style=
                  ([StyleSheet.absoluteFill],
                   backgroundColor: "#8BED4F", width: CaloriePercentage )
                
              />
            </View>
            <Text>Fat: this.state.CalsFatInput</Text>
            <Text>Carbs: this.state.CalsCarbsInput</Text>
            <Text>Protein: this.state.CalsProteinInput</Text>
          </View>

          <View>
           

【问题讨论】:

【参考方案1】:

setState 是异步的,所以如果你调用setState 然后立即尝试访问它的值,它们将会是旧的。

您可以将可用的回调用作setState、check that out here 的第二个参数,也可以只使用用于设置状态的值并将其传递到文件系统进行存储。

如果这还不够合理,请告诉我。

【讨论】:

您好,我不确定链接是否正确,请确认。并且肯定异步存储允许用户在切换屏幕时保持状态? 谢谢,奇怪的是链接是错误的,我会更新它。并且异步存储应该可以工作,但是如果您使用旧数据设置它,则下一个屏幕中不会有新数据。

以上是关于如果我使用异步存储,当我更改屏幕时,我的值怎么会重置为 0?的主要内容,如果未能解决你的问题,请参考以下文章

注销和登录后屏幕变黑

如果尝试进入登录屏幕,Laravel 5 会重定向到主页

如果可以使用复选框更改多行值?

SwiftUI 和 CloudKit 异步数据加载

React 路由器会短暂显示登录屏幕,然后如果用户已登录,则会重定向到仪表板

应用内购买截图