Search code examples
reactjsstatereduxmutation

Replace array item with another one without mutating state


This is how example of my state looks:

const INITIAL_STATE = {
 contents: [ {}, {}, {}, etc.. ],
 meta: {}
}

I need to be able and somehow replace an item inside contents array knowing its index, I have tried:

      return {
        ...state,
        contents: [
          ...state.contents[action.meta.index],
          {
            content_type: 7,
            content_body: {
              album_artwork_url: action.payload.data.album.images[1].url,
              preview_url: action.payload.data.preview_url,
              title: action.payload.data.name,
              subtitle: action.payload.data.artists[0].name,
              spotify_link: action.payload.data.external_urls.spotify
            }
          }
        ]
      }

where action.meta.index is index of array item I want to replace with another contents object, but I believe this just replaces whole array to this one object I'm passing. I also thought of using .splice() but that would just mutate the array?


Solution

  • Splice mutate the array you need to use Slice . And you also need to concat the sliced piece .

    return Object.assign({}, state,  {
             contents:
              state.contents.slice(0,action.meta.index)
              .concat([{
                content_type: 7,
                content_body: {
                  album_artwork_url: action.payload.data.album.images[1].url,
                  preview_url: action.payload.data.preview_url,
                  title: action.payload.data.name,
                  subtitle: action.payload.data.artists[0].name,
                  spotify_link: action.payload.data.external_urls.spotify
                }
              }])
              .concat(state.contents.slice(action.meta.index + 1))
      }