【问题标题】:How come my value gets reset to 0 when I change screen if I am using async storage?如果我使用异步存储,当我更改屏幕时,我的值怎么会重置为 0?
【发布时间】: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>
           

【问题讨论】:

    标签: javascript ios reactjs react-native


    【解决方案1】:

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

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

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

    【讨论】:

    • 您好,我不确定链接是否正确,请确认。并且肯定异步存储允许用户在切换屏幕时保持状态?
    • 谢谢,奇怪的是链接是错误的,我会更新它。并且异步存储应该可以工作,但是如果您使用旧数据设置它,则下一个屏幕中不会有新数据。
    猜你喜欢
    • 1970-01-01
    • 2019-06-15
    • 1970-01-01
    • 2016-12-19
    • 1970-01-01
    • 1970-01-01
    • 2017-08-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多