0

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>

1 Answer 1

1

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({}).

Sign up to request clarification or add additional context in comments.

1 Comment

I've updated my answer to address your question and I added some more details on how you could go about solving your problem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.