首页 > 解决方案 > 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.

标签: reactjsformikimmer.js

解决方案


我不确定我是否理解这个问题,因为目前还不清楚为什么你首先需要 deepClone,除非你的减速器有副作用并且改变了有效载荷而不是状态。在这种情况下,您也可以调用produce有效负载数据,例如:

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
     }
  })
}

推荐阅读