简体   繁体   中英

How do I save state when getting values from navigation props? React-native

I have two screens, the main screen Macros.js, where I can set my target calories, and add calories manually. On another screen I have an API which searches a food database, and when I click on them, I sent the values to my main screen through props.navigation:

Tracker.js

<Button
            title="Macros"
            onPress={() =>
              navigate("Macros", {
                totalCals: totalCals,
                totalCarbs: totalCarbs,
                totalProtein: totalProtein,
                totalFat: totalFat,
              })

For some reason I can only show the values I pressed, rather than adding it to my UsedDailyCalorie state inside Macros.js. So essentially it resets every time I search and add a new food. I believe I have async storage working properly, so state should be saved and retrieved when that screen resumes.

Here is my Macros.js

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,
    };

  }

Where I add calories manually inside the screen.

addMacrosManually = (ProteinInput, FatInput, CarbsInput) => {

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

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


    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);
    }

  };

getData = async () => {

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

    } catch(e) {
      // read error
    }
  };

Render Method

render() {
    console.log(this.state.UsedDailyCalories);
    const { navigate } = this.props.navigation;
    let CaloriePercentage = this.state.CaloriePercentage + "%";

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

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

    return (
      //styling for navigation container
      <View style={styles.container}>
        <View style={styles.topStyle}>
          <Text>{calsTakenFromTracker} </Text>
          <Text>{totalCarbs} </Text>

I think the problem is your call to this.setState({}) inside addMacrosManually . This has the effect of resetting your state.


If you have a property of type number that you want to increase by a certain amount you would do something like this:

Make sure the prop has an initial value:

// ...
this.state = {
   test: 0,
};
// ...

Use the previous state value of the property and add a number to it:

this.setState({test: this.state.test + 1});

If this.props.navigation.getParam("totalFat", "nothing sent") is a number you can replace the 1 in the above example with the params you received on navigate.


The + operator is described on mdn as follows:

The unary plus operator (+) precedes its operand and evaluates to its operand but attempts to convert it into a number, if it isn't already.

So this wouldn't prevent a property from being reset when the entire state is reset by a call like this.setState({}) .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM