反应,如何不进行深克隆而不突变状态?

时间:2020-06-05 05:15:01

标签: reactjs formik immer.js

您以某种状态(可能是redux状态)存储了数据

并且您正在使用formik修改数据。

在代码中,

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

//减速器看起来像

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

注意,我正在将data克隆到_.cloneDeep(data)中,以防止状态发生变化。
当数据平坦时,可以放心使用{...data},但是当数据很深(具有对象的对象)不是那么容易

除了深度克隆,还有其他方法吗? 我想知道immer.js是否可以在这里提供帮助。

1 个答案:

答案 0 :(得分:0)

我不确定我是否理解这个问题,因为目前尚不清楚为什么首先需要使用deepClone,除非您的reducer有副作用并且会改变有效负载而不是状态。在这种情况下,您也可以在有效载荷数据上调用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
     }
  })
}