user3348410
user3348410

Reputation: 2833

How add item in nested array of object in redux reducer

Here is my example initial state:

let initialState = {
    data: {
        name: 'john',
          books: [
              {
                  name: 'a',
                  price: 220
              }
          ]
    }
}

How I can add new book item to books ?

I tried already

return {
        ...state,
        data :{
          ...state.data,
          books:{
              ...state.data.books,
              name : state.data.books.concat(action.payload.item.name),
              price : state.data.books.concat(action.payload.item.price)
          }
      }
      };

Any idea for that?

Important: I don't want to delete item which already in books I want to add new one with action payload

Upvotes: 2

Views: 1769

Answers (4)

The answer is easy look at this

const book = {
            name : action.payload.item.name,
            price : action.payload.item.price
           };
return {
    ...state,
    data :{
      ...state.data,
      books: state.data.books.concat(book)              
      }      
};

you can find immutable update patterns here

Redux updated patterns

Upvotes: -1

Mulan
Mulan

Reputation: 135217

Let's make our jobs easier by inventing tools of convenience -

const update = (key, { [key]: value, ...state }, f) =>
  ({ ...state, [key]: f (value) })

const initState =
  { data:
      { name: "john"
      , books: [ { name: "a", price: 20 } ]
      }
  }

const payload =
  { item: { name: "b", price: 30 } }

const nextState =
  update ('data', initState, x =>
    update ('books', x, arr =>
      [ ...arr, payload.item ]
    )
  )

console.log(initState)
console.log(nextState)

Output

// initState
{ data:
    { name: "john"
    , books:
        [ { name: "a", price: 20 } ]
    }
}

// nextState
{ data:
    { name: "john"
    , books:
        [ { name: "a", price: 20 }
        , { name: "b", price: 30 }
        ]
    }
}

Upvotes: 0

Clarity
Clarity

Reputation: 10873

First of all, books is array. Second, if you want just to add a new item to the array, you can use array spread operator.

books: state.data.books.concat(action.payload.item) would also work.

return {
  ...state,
  data: {
    ...state.data,
    books: [
      ...state.data.books,
      action.payload.item
    ]
  }
};

Upvotes: 0

Dominik Matis
Dominik Matis

Reputation: 2146

You missed some braces there, especially, books is array and you are inserting new object

return {
        ...state,
        data: {
          ...state.data,
          books: [
              ...state.data.books,
              {
                  name: action.payload.item.name,
                  price: action.payload.item.price
              }
          ]
      }
};

Upvotes: 6

Related Questions