1

I'm practicing React with Redux and in this stage edit or update a nested array. I can't get it to work for me.

State default (array of objects):

[
{
  "id": 10,
  "title": "president",
  "totalParticipants": 0,
  "desc": "Selects a new member to represent",
  "options": [
    {
      "id": 1408,
      "nameOption": "Kim",
      "vote": 0,
      "checked": false
    },
    {
      "id": 1527,
      "nameOption": "North",
      "vote": 0,
      "checked": false
    }
  ]
},
{
  "id": 11,
  "title": "best players",
  "totalParticipants": 0,
  "desc": "Selects a new best player",
  "options": [
    {
      "id": 150,
      "nameOption": "Jhon",
      "vote": 0,
      "checked": false
    },
    {
      "id": 152,
      "nameOption": "Gerald",
      "vote": 0,
      "checked": false
    },
    {
      "id": 153,
      "nameOption": "Sofi",
      "vote": 0,
      "checked": false
    }

  ]
},
]

I have a function reducer

case 'ADD_VOTE':
  const getPoll = action.values.map(poll => poll);

  // get index to option
  const optionIndex = getPoll.map(dat => (
    dat.options.findIndex(opt => opt.id === action.id)
  ));

  // get value to options
  // const option = action.vote.map(opt => opt.options[projectIndex]);
  const optionVal = action.values.map(poll => (
    poll.options[optionIndex]
  ))
         
  const nextPoll = {
    ...action.values,
    options:[
      { vote:  + 1  }
    ]
  };
       
  return {
    ...state,
    nextPoll
  }

And function action

export const addVotePoll = ({ id }, values) => ({
  type: 'ADD_VOTE',
  id,
  values,
})

When I throw dispatch event it passes idSelected and data of poll current.

For example: I will select name option "KIM" (state default), then send id (1408) and send data of poll... (idPoll, title, desc, option, etc).

I read something about immutable.js but I haven't tried it yet.

1
  • return { ...state, ...nextPoll } would make much more sense, but this will still clear options, because you didn't include the old value Commented Nov 15, 2022 at 0:03

1 Answer 1

3

From what I understand of your description, you are trying to dispatch the addVotePoll action to increment the vote count of a specific entry in the options array by id. To apply the immutable update pattern you must shallow copy all state, and nested state, that is being updated.

Example:

case 'ADD_VOTE':
  // return shallow copy of state array
  return state.map(poll => poll.id === action.values.idPoll
    ? {
      ...poll,                    // <-- shallow copy current state
      options: poll.options.map(  // <-- shallow copy options
        option => option.id === action.id
          ? {
            ...option,             // <-- shallow copy matched option
            vote: option.vote + 1, // <-- update specific property
          }
          : option
      ),
    }
    : poll
  );
Sign up to request clarification or add additional context in comments.

10 Comments

@Rioko Can you clarify what "now i have the new array but need add this array a poll" means?
@Rioko Sorry, what poll and what array are you referring to? The only array I see in your code is the options array. Are you trying to add another property to the state?
@Rioko I see, so the state is an array of objects (polls?), and in these objects is an options array. Are you asking then how to update a specific poll object?
@Rioko Ok, and so values is the poll object with the pollId property to match up to one of the outer array elements?
@Rioko Ok, thanks for all the clarification, I've updated my answer with what I believe to be the understanding.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.