0

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?

5
  • your Items must have a unique key or id so you can select them and then update them Commented Jan 13, 2021 at 10:31
  • Did you tried console.log payload send to app.SELECT action? Wha's payload?
    – cuongdevjs
    Commented Jan 13, 2021 at 10:37
  • 1
    Your reducer does not change the items property of your state, but the action.payload.key property (in this case, Operation.)
    – phtrivier
    Commented Jan 13, 2021 at 10:39
  • Cường Mạnh Nguyễn, using "console.log(items = ${JSON.stringify(this.props.itemsProp)});" in handleChange-method, I see "items = [{"Date":1,"Operation":"revenue"}]"
    – Jelly
    Commented Jan 13, 2021 at 12:42
  • phtrivier, you are right. This is the problem source. I gave the answer on my question, taking into account it.
    – Jelly
    Commented Jan 13, 2021 at 16:25

2 Answers 2

1

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;
  }
}
0

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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.