Immer: Cannot perform get on revoked proxy error when no recursion

Created on 6 Mar 2018  路  4Comments  路  Source: immerjs/immer

Similar to https://github.com/mweststrate/immer/issues/100, I'm getting
TypeError: Cannot perform 'get' on a proxy that has been revoked
from a test after converting a reducer to immer.

I narrowed the code down from the original to a minimal example, which is why it looks odd.

export default (state, action) =>
  produce(state, draft => {
    switch (action.type) {
      case types.SET_STARTING_DOTS:
        return draft.availableStartingDots.map(a => a);
      default:
        break;
    }
  });

The above reducer will raise the error when given this state and the SET_STARTING_DOTS action:

{
    availableStartingDots: [
      { dots: 4, count: 1 },
      { dots: 3, count: 2 },
      { dots: 2, count: 3 },
      { dots: 1, count: 4 }
    ]
}

Changing the case to return state.availableStartingDots.map(a => a); removes the error.

Most helpful comment

@TrueWill I fixed the issue that the result set was not properly finalized. However, I am pretty sure that this reducer is not doing what you intend it to do; you return a sub part of the original state, effectively changing its shape.

Your reducer now transforms the state:

{
    availableStartingDots: [
      { dots: 4, count: 1 },
      { dots: 3, count: 2 },
      { dots: 2, count: 3 },
      { dots: 1, count: 4 }
    ]
}

into

  [
      { dots: 4, count: 1 },
      { dots: 3, count: 2 },
      { dots: 2, count: 3 },
      { dots: 1, count: 4 }
    ]

What you probably want is:

case types.SET_STARTING_DOTS:
        draft.availableStartingDots = draft.availableStartingDots.map(a => a);
        return

All 4 comments

@TrueWill I fixed the issue that the result set was not properly finalized. However, I am pretty sure that this reducer is not doing what you intend it to do; you return a sub part of the original state, effectively changing its shape.

Your reducer now transforms the state:

{
    availableStartingDots: [
      { dots: 4, count: 1 },
      { dots: 3, count: 2 },
      { dots: 2, count: 3 },
      { dots: 1, count: 4 }
    ]
}

into

  [
      { dots: 4, count: 1 },
      { dots: 3, count: 2 },
      { dots: 2, count: 3 },
      { dots: 1, count: 4 }
    ]

What you probably want is:

case types.SET_STARTING_DOTS:
        draft.availableStartingDots = draft.availableStartingDots.map(a => a);
        return

Released as 1.1.3. Thanks for reporting!

@mweststrate Yep - I changed the shape to keep the example as simple as possible. The original code preserves shape. Thank you! 馃槂

Just tested it - works fine! Great job!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

steida picture steida  路  4Comments

toli444 picture toli444  路  6Comments

FredyC picture FredyC  路  4Comments

dfadev picture dfadev  路  6Comments

drcmda picture drcmda  路  6Comments