0

I have this set of data

this.state = { weeks: [ { weekNumber: 1, weights: [] }, { weekNumber: 2, weights: [] } ] }

What I want to do is create a new array and set it to 'weights'. I've checked other posts like this one: Set state of nested array

I assume I do something similar.

Edit: Also, say for instance I want to update each individual week's weights array, how would I go about doing that?

5
  • Are you trying to create a new entry in state called "weights" or create a variable called "weights"? Commented Apr 4, 2019 at 1:02
  • @CodySwann I figured I would create a new array variable and use that new array variable to update the state 'weights' Commented Apr 4, 2019 at 1:06
  • 1
    @Bpicks - take a look at react's immutability helpers—specifically, the update method. You can create a new state object and then use setState to update your entire state with the updated state. reactjs.org/docs/update.html Commented Apr 4, 2019 at 1:10
  • @heyitsjhu beat me to it. That's the best way. Otherwise, you have to do some nasty object extensions with the spread operator Commented Apr 4, 2019 at 1:19
  • @CodySwann `@heyitsjhu Ok, say for instance I want to update both weeks' weights' arrays. Would I just map through each week and update the state using the update method from immutability helpers? Commented Apr 4, 2019 at 1:42

2 Answers 2

1

I usually use this solution:

const newWeeks = [ ...this.state.weeks ];
newWeeks[0] = { ...newWeeks[0] };
//modify `newWeeks`

this.setState({
  weeks: newWeeks
});

Update 1: Live version: https://codesandbox.io/s/20v7r2zx0j?fontsize=14&module=%2Fsrc%2FTest.js


Update 2: thank @bird. Problem is Spread only goes one level deep when copying an array(or object), so we need an extra step here:

newWeeks[0] = { ...newWeeks[0] };
Sign up to request clarification or add additional context in comments.

3 Comments

This is not the way to clone a nested object. The weight property still a reference. Modified the newWeeks[0].weight cause change to this.state.weeks[0].weight also.
Hi, you can see I created new array from old array using Spread syntax, It create new array with value, not reference, read more about it here > developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Just put console.log(this.state.weeks); at line 21 in your code sandbox, right after the newWeeks[0].weights = [1, 2, 3]; line. You will see the weeks[0].weights also modified, when setState action doesn't run yet.
0

Because it's a nested object, then you can clone with native javascript code with JSON.parse(JSON.stringify(obj))

this.state = {
    weeks: [
        {
            weekNumber: 1,
            weights: []
        },
        {
            weekNumber: 2,
            weights: []
        }
    ]
}

const newWeeks = JSON.parse(JSON.stringify(this.state.weeks))

newWeeks[0].weights = [1,2,3]

this.setState({weeks: newWeeks})

The other normal clone like: [...this.state.weeks] or Object.assign([], this.state.weeks) only clone properties of level 1 not the nested, in your case, the weight property will not be cloned, just copied the reference in a normal way.

You can take a look at cloneDeep of lodash lib or use immer to archive your goal, also.

Comments

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.