Search code examples
javascriptreactjsreduxreact-reduximmutability

how to change or update the specific value of the state immutably


I'm new to js and react js with redux i'm trying to update a value of the global state immutably This is my current state

const initialState = {
  questions: [
    {
      id: 1010,
      name: "Inside which HTML element do we put the JavaScript?",
      questionTypeId: 1,
      options: [
        {
          id: 10,
          name: "javascript",
          isAnswer: false,
          isSelected: false
        },
        {
          id: 11,
          name: "scripting",
          isAnswer: false,
          isSelected: false
        },
        {
          id: 12,
          name: "script",
          isAnswer: true,
          isSelected: false
        },
        {
          id: 13,
          name: "js",
          isAnswer: false,
          isSelected: false
        }
      ]
    },
    {
      id: 1011,
      name: "Javascript is a langague used for ?",
      questionTypeId: 2,
      options: [
        {
          id: 14,
          name: "ConsoleApp",
          isAnswer: false,
          isSelected: false
        },
        {
          id: 15,
          name: "ShellApp",
          isAnswer: false,
          isSelected: false
        },
        {
          id: 16,
          name: "WebApp",
          isAnswer: true,
          isSelected: false
        },
        {
          id: 17,
          name: "MobileApp",
          isAnswer: false,
          isSelected: false
        }
      ]
    },
    {
      id: 1012,
      name: "What is the full form of SPA?",
      questionTypeId: 3,
      options: [
        {
          id: 18,
          name: "Secured and Progressive App",
          isAnswer: false,
          isSelected: false
        },
        {
          id: 19,
          name: "Single Page Application",
          isAnswer: false,
          isSelected: false
        },
        {
          id: 20,
          name: "SOLID Principles for Application",
          isAnswer: true,
          isSelected: false
        },
        {
          id: 21,
          name: "None of the above",
          isAnswer: false,
          isSelected: false
        }
      ]
    }
  ],
  Currentquestion: []
};

i would like to change the isSelected value to true from the questions array of which index having questionTypeId:1 followed by the options array of index:0 Below is the reducer i tried to change the state immutably action.payload value from the ui is 1 and action.value's value from the ui is 0

case SELECT_ANS: {
      const question = action.payload;
      const index = action.value;
      // const newstate = produce(state, draftsate => {
      //   draftsate.questions[question].options[index].isSelected = true;
      // });
      return {
        ...state,questions:[
          {
            ...state.questions[question],options:[{
              ...state.questions[question].options[index],isSelected:true
            }]
          }
        ]
          ]
        ]
      };

I try to put all the information as much as i can if anything missing or inappropriate i'm sorry about ,Any help with explanation would be really appriciated ,Thanks in Advance


Solution

  • At first I notices you split your action's data into action.payload and action.value, this is against the flux principles. You must put your data object in action.payload and get it like action.payload.questionTypeId and action.payload.index.

    Well, you can change your store like

    case SELECT_ANS: {
      return {
        ...store,
        questions: store.questions.map((question) => {
          if (question.questionTypeId === action.payload.questionTypeId) {
            return {
              ...question,
              options: question.options.map((option, index) => {
                if (index === action.payload.index) {
                  return {
                    ...option,
                    isSelected: true,
                  };
                }
    
                return option;
              }),
            };
          }
    
          return question;
        }),
      };
    };
    

    If I didn’t answer your question well enough, you can get more information in redux docs or ask me personally.

    Good luck learning!