0

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.

eugene
  • 39,839
  • 68
  • 255
  • 489
  • How does your reducer look like? That is the part of your code to make sure that you aren't directly mutating your state – wentjun Jun 05 '20 at 05:18
  • my reducer uses immer.js and not mutating the data, but I still have to clone the data here because otherwise I would be mutating the state directly. – eugene Jun 05 '20 at 05:20
  • updated the reducer part @wentjun – eugene Jun 05 '20 at 05:30

1 Answers1

0

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
     }
  })
}
mweststrate
  • 4,890
  • 1
  • 16
  • 26