简体   繁体   中英

react, how to not mutate state without deepcloning?

You have data stored in a state (possibly redux state)

and You are using formik to modify your data.

In code,

 let { data } = props // from redux state

 // suppose data is somewhat deep like



   // data = {
   //   p1: {
   //     p11: {
   //     },
   //     p12: [{
   //       p122
   //     }, {
   //       p123
   //     }]
   //   },
   //   p2
   // }


   const handleSubmit = (values) => {

     dispatch({
       type: 'setData',
       payload: {
         data: values
       }
     })
   })

 <Formik initialValues={_.cloneDeep(data)} enableReinitialize onSubmit={handleSubmit} />

// reducer looks like

const reducer = (state={}, action) => {
  return produce(state, (draft) => {
     if (action.type === 'setData') {
         draft.data = action.payload.data
     }
  })
}

notice I'm cloning data with _.cloneDeep(data) to prevent mutating the state.
When data is flat, it's safe to get away with {...data} but when data are deep (have objects that have objects) it's not that easy

Is there an alternative way than deep cloning? I was wondering if immer.js could help here.

I'm not sure I understand the question as it is unclear why you need the deepClone in the first place, unless your reducer has side effects and mutates the payload rather than the state. In that case you can call produce on the payload data as well, for example:

const reducer = (state={}, action) => {
  return produce(state, (draft) => {
     if (action.type === 'setData') {
         const dataToStore = produce(action.payload, payloadDraft => {
             payloadDraft.name = payloadDraft.name.toUpperCase()
         })
         draft.data = dataToStore
     }
  })
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM