How to change nested Object without mutating it in

2019-08-04 12:17发布

问题:

I am pretty new guy to redux.I am little bit confused that how to change this data without mutating it.

my data structure like this

    {
      postOwnwerName:"",
        postTags:[],
        photos:[

          {  
            id:dc5c5d7c5s,
            caption:null


            },
             {  
            id:dccccccc5s,
            caption:null


            }





        ],
   }

Whent this function fires

this.props.updateCaption(id,caption)

my Reducer should set data according to the id in the data structure without mutating it

import * as types from '../Actions/actionTypes';

const initialState = {
    postOwnwerName:"",
    postTags:[],
    photos:[],
};

export default function uploadReducer(state=initialState,action) {
    switch (action.type){
        case types.SETPHOTOSTATE:
            return Object.assign({},state,{ photos:state.photos.concat(action.payload) });
        case types.SETCAPTIONTEXT:

     //this method is not working
            return (
                Object.assign({},state,state.photos.map((data) => {
                    if(data.id == action.payload.id){
                        return Object.assign({},data,{caption:action.payload.caption})
                    }else{
                        return data
                    }
                }))
            )
        default:
            return state
    }
}

回答1:

if the state object has many level it will be difficult to change state without mutating. In those scenario I first copy the state deeply and then make changes to the new state and return new state. See here Cloning object deeply. You can try this once.

export default function uploadReducer(state=initialState,action) {
  let newState = JSON.parse(JSON.stringify(state));
  switch (action.type){
    case types.SETPHOTOSTATE:
       newState.photos.push(action.payload);
       return newState;
    case types.SETCAPTIONTEXT:
       newState.photos.map((data) => {
         if(data.id == action.payload.id){
           data.caption = action.payload.caption;
         }
       });
       return newState;
   default:
     return newState;
   }
}