2

I was hoping to be able to update a state object from this:

this.state = {
          items: {},
}

to this:

this.state = {
          items: {
              2020-01-01: [
                     {'text': 'Some text', 'start_time': 'Some time'},
                     {'text': 'Some text', 'start_time': 'Some time'}],
              2020-01-02: [
                     {'text': 'Some text', 'start_time': 'Some time'},
                     {'text': 'Some text', 'start_time': 'Some time'}]
          }
}

by using spread operator:

//response from the API
response.items.map((item, index) => {
  this.setState(prevState => ({
           items: {
             ...prevState.items,
             [item.time]: [
               ...prevState.items[item.time], 
               {
                'text': item.summary,
                'start_time': item.start_time
               }]
           }
  }))
});

but that generates a TypeError:

TypeError: Invalid attempt to spread non-iterable instance

The purpose of updating the state object in such way is to render this component with data pulled from an API. But I can't seem to get it right.

1
  • seems not clear, why not first loop and create the object first or use Array.reduce, and once object built, you set the state to avoid inconsistencies ? Commented Aug 26, 2019 at 22:26

1 Answer 1

4

No matter what time is in the .map, it does not exist as a property of items in the initial state, the first time this code is run:

const initialState = {
  items: {},
};

const time = '2020-01-01';
const newState = ({
  items: {
    ...initialState.items,
    [time]: [
      ...initialState.items[time],
      {
        'text': item.summary,
        'start_time': item.start_time
      }
    ]
  }
});

Alternate with the empty array instead, so that it can be spread properly:

...(initialState.items[time] || []),

const initialState = {
  items: {},
};

const item = { summary: 'foo', start_time: 'bar' };

const time = '2020-01-01';
const newState = ({
  items: {
    ...initialState.items,
    [time]: [
      ...(initialState.items[time] || []),
      {
        'text': item.summary,
        'start_time': item.start_time
      }
    ]
  }
});
console.log(newState);

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

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.