Jelly
Jelly

Reputation: 1298

React-redux: Update value in array

As an initial state I use array of objects:

   export default{
      items: [
          {
            Date: 1,
            Operation: 'revenue',
          }
       ]
   }

In component I dispatch the action, which must update one element in object of array: "Operation"

 const mapDispatchToProps = (dispatch) => {
        return {
            selectOperation: (input) => dispatch({type: app.SELECT, payload: input})
         }
  };

   class OperationSelect extends React.Component {
      // constructor

      handleChange(event) {
         this.props.selectOperation({
            key: 'Operation',
            value: event.target.value
          });
      };

     // render() logic 
  }

 export default connect(null, mapDispatchToProps)(OperationSelect)

Reducer:

 import initialState from '../constants/initialState';
 import { app } from '../constants/types';

 export default function update(state = initialState,  action) {
    switch (action.type) {
        case app.SELECT:
            return {
                ...state,
                [action.payload.key]: state.items.map(
                    (item, i)=> i===0 ? {...item, Operation: action.payload.value}
                    : item
                )
              };
        default:
            return state;
       }
   }

But, when I select new value and application run handleChange, dispatch the action, run reducer, the state in store keeps the old value of "Operation".

What am I doing wrong?

Upvotes: 0

Views: 163

Answers (2)

Jelly
Jelly

Reputation: 1298

The problem was in that I did not update in reducer the state of array. This is a working code:

 export default function update(state = initialState,  action) {
    switch (action.type) {
      case app.SELECT:
        return {
            ...state,
            items: state.items.map(
                (item, i)=> i===0 ? {...item, [action.payload.key]: action.payload.value}
                : item
            )
          };
      default:
          return state;
    }
}

Earlier in return-block I used [action.payload.key] in place, where "items" should have used. So I updated "Operation" in place, where "items" updated.

Upvotes: 0

Taghi Khavari
Taghi Khavari

Reputation: 6582

This is I think what you need to do:

first add an id property to your items and then do something like this:

export default {
  items: [
    {
      id: 0,
      Date: 1,
      Operation: "revenue",
    },
  ],
};
class OperationSelect extends React.Component {
  // constructor

  handleChange(event) {
    this.props.selectOperation({
      key: "Operation", // I think you need to check this and try to findout that you need this or not
      value: event.target.value,
      id: 0 // 0 is just an example you need to decide how you would implement the id
    });
  }

  // render() logic
}


export default function update(state = initialState, action) {
  switch (action.type) {
    case app.SELECT:
      return {
        ...state,
        items: state.items.map((item, i) =>
          i === action.payload.id ? { ...item, Operation: action.payload.value } : item
        ),
      };
    default:
      return state;
  }
}

Upvotes: 1

Related Questions