1

What's wrong with below code?

this.setState({
  album: {
    ...this.state.album,
    photos: [
      ...this.state.album.photos,
      { url : newUrl }
    ]
  }
})

It worked if photos have something, but if album is an empty object, I will got this error

Cannot convert undefined or null to object
Xie Xie Fang
  • 181
  • 3
  • 9

3 Answers3

3

You can also use: (...this.state.album.photos || []) so it parses the empty array at first:

const state = {
  album: {
    photos: undefined
  }
}

const newState = {
  album: {
    ...state.album,
    photos: [
      ...(state.album.photos || []),
      { url: 'newUrl' }
    ]
  }
}

console.log(newState)
Hemerson Carlin
  • 7,354
  • 1
  • 27
  • 38
0

Yeah, that's the expected behaviour. The spread operator (...) will spread, that is, expand everything provided. If that's null, it can't possibly do that, right?

You can try something like:

...( Object.assign( {}, this.state.album.photos )
weirdpanda
  • 2,521
  • 1
  • 20
  • 31
  • The `...` is the spread operator. `Object.assign()` will give us a new object based on the `photos` property. If it's null, it'll be an empty object and, hence, the spread operator will do nothing. However, if it does have content, it'll just spread it normally. – weirdpanda Feb 02 '18 at 07:31
0

Use Short circuit evaluation concept and put ||[] with state.albums.photos, if albums will be blank object then (photos=undefined || []) will return an empty array.

Use this:

this.setState(prevState => ({
    album: {
        ...prevState.album,
        photos: [
            (...prevState.album.photos || []),
            { url : newUrl }
        ]
    }
}))

Use updater function and prevState to compute the next state value.

Mayank Shukla
  • 100,735
  • 18
  • 158
  • 142