2

I have a wizard based GUI where I need to create a copy of some original state in my redux store and save it to a new property called stageEdits that can be used as a temporary place to make changes which can then be saved back to the original state, or discarded...

My first attempt was to use immer and nested produce functions like so:

const reducer = (state, action) => {
  return produce(state, (draftState) => {
    switch (action.type) {
      case ActionName.EditStage:
        const stage = findStageById(draftState, action.stageId);
        draftState.stageEdits = produce(stage, (draftStage) => {
          draftStage.isEditing = true;
        }
        break;
    }
  });
};

however, this resulted in TypeError: Cannot perform 'get' on a proxy that has been revoked which appears to be an issue when trying to use nested producer functions... so I'm not sure if this is the correct way to approach this...

Should I be using something like loDash cloneDeep, or is there a better way to do this?

UPDATE This question is specifically about how to create a deepCopy of state inside the Immer produce function... right now, when I try to use cloneDeep against the draftState proxy object returned by Immer, anything that is an array is returned as a number instead of a copy of the array itself...

based on the link provided by @azundo, I ended up cloning the originalState instead of the draftState... this fixed my problem... see the revised code below for example:

import cloneDeep from 'lodash/cloneDeep';

const reducer = (currentState, action) => {
  return produce(currentState, (draftState) => {
    switch (action.type) {
      case ActionName.EditStage:
        const stage = findStageById(currentState, action.stageId);
        draftState.stageEdits = cloneDeep(stage);
        break;
    }
  });
};
Joshua Barker
  • 987
  • 2
  • 11
  • 23
  • Pick `clone` over `lodash`, it's 2kb whilst `lodash` is 70kb – Aleks Jul 31 '19 at 00:30
  • @Aleks if you import like `lodash/clone` it will be 2kb too – Jee Mok Jul 31 '19 at 00:34
  • Possible duplicate of [What is the most efficient way to deep clone an object in JavaScript?](https://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-deep-clone-an-object-in-javascript) – Jee Mok Jul 31 '19 at 00:36
  • 1
    Have you checked out the `original` function from `immer`? That might be what you want to wrap `stage` in before passing it to your nested producer. That requires that you haven't edited `stage` in the outer producer since you're getting the original non-proxied stage without any edits. https://github.com/immerjs/immer#extracting-the-original-object-from-a-proxied-instance – azundo Jul 31 '19 at 06:14
  • Thanks @azundo... that link helped lead me to the eventual answer... rather than cloning the draftState, I needed to clone the currentState instead... that fixed my problem... – Joshua Barker Aug 02 '19 at 19:03

0 Answers0