Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

[React] Updating Nested Arrays with setState()

I am trying to update state using React's setState(), but my state has nested arrays of objects. I tried mapping these but it doesn't seem to update and I can't find a way to log out the response from the method to see what's happening.

I have verified that the function is being properly triggered and the IDs are properly sent to the function.

Here's my setState() method:

  toggleCheckboxAt = (categoryIndex, checkboxIndex) =>
    this.setState({
      categories: this.state.categories.map((category, index) => {
        if (index === categoryIndex) {
          category.checkboxes.map((checkbox, index) => {
            if (index === checkboxIndex) {
              return {
                ...checkbox,
                isChecked: !checkbox.isChecked
              };
            }
            return checkbox;
          });
        }
        return category;
      })
    });

Does anyone know what might be causing the issue?

2 Answers

I solved this now. I was updating the checkboxes item regardless of whether the category was the selected category, so I had to simply return just the category if there were no changes.

Here's the code in case it helps anyone else:

  toggleCheckboxAt = (categoryIndex, checkboxIndex) =>
    this.setState({
      categories: this.state.categories.map((category, index) => {
        var checkboxes;
        if (index === categoryIndex) {
          ingredients = category.checkboxes.map((checkbox, index) => {
            if (index === checkboxIndex) {
              return {
                ...checkbox,
                isChecked: !checkbox.isChecked
              };
            }
            return checkbox;
          });
          return {
            ...category,
            checkboxes: checkboxes
          };
        }
        return category;
      })
    });

Thanks for the help!

Seth Kroger
Seth Kroger
56,413 Points

Let me draw your attention to this part:

        if (index === categoryIndex) {
          category.checkboxes.map( /* ... */); // <- map gives you a new array.
              // it's not stored in a variable or returned, 
              // so the results are effectively dumped
        }
        return category;

Thank you for the reply!

I added a variable to store the array and used console.log() to ensure that an array is properly returned, but after the state updates, I am getting an errors that says the checkboxes array is undefined. In the console, the array appears correctly returned, but there is a word "undefined" that appears by it.

Here's the code at this point:

  toggleCheckboxAt = (categoryIndex, checkboxIndex) =>
    this.setState({
      categories: this.state.categories.map((category, index) => {
        var checkboxes;
        if (index === categoryIndex) {
          checkboxes = category.checkboxes.map((checkbox, index) => {
            if (index === checkboxIndex) {
              return {
                ...checkbox,
                isChecked: !checkbox.isChecked
              };
            }
            return checkbox;
          });
        }
        console.log(checkboxes);
        return {
          ...category,
          checkboxes: checkboxes
        };
      })
    });

If I manually set the array, then it all works properly:

...
return {
  ...category,
  checkboxes: [{ name: "checkbox 1", isChecked: true}]
}
...

If you have any thoughts, it would be enormously appreciated!