1

So based on a recent answer, I've started using ReduxStarterKit, which uses Immer in it's slice function. Overall, I think the basic idea is brilliant.

Unfortunately, when I try to actually make use of immer to make my life easier, I run into issues. I've tried to simplify what I'm doing using my test reducer, and I'm still getting the same basic problem. I've also turned off all my middleware (ElectronRedux) to make sure it's not a problem there. The following is a simplified test reducer I'm using for testing:

const CounterSlice = createSlice({
  name: 'counter',
  reducers: {
    increment: (state) => { state.value = state.value + 1 },
    decrement: (state) => { state.value = state.value - 1 }
  },
  initialState: { value: 0 },
})

The code above is pretty simple, and as far as I can tell exactly what Immer/ReduxStarterKit wants me to write. Despite this, when I call the code I'm getting an error: Uncaught Error: Immer drafts cannot have computed properties

What am I doing wrong?

Edit:

I just put together a simple demo app, just for the purposes of testing the basics. The counter slice has coded here works perfectly. I guess this is an interaction between Immer and another package -- just not sure where to go about debugging which one. Is it a redux version issue, is it electron, electron redux, typescript, webpack, the list goes on and (painfully) on.

I may have to recreate my basic app environment and test this one painful step at a time. Ugh!

zastrowm
  • 8,017
  • 3
  • 43
  • 63
RonLugge
  • 5,086
  • 5
  • 33
  • 61
  • 1
    Hmm. Some googling turns up https://github.com/immerjs/immer/issues/317 and https://stackoverflow.com/questions/57505319/immer-drafts-computed-properties with the same error message, but not a clear answer. I haven't seen this error before - I'll try to look into it soon. I suspect it _may_ be due to the use of `state.value` on both sides of the expression. What happens if you do `state.value++`, or `const {value} = state; state.value = value + 1` ? – markerikson Nov 08 '19 at 23:57
  • @markerikson same exact issue for `state.value++`, and I'll get back to you if `state.value = value + 1` makes a difference. FYI, I cannot see how how the latter could cause an issue -- state.value is just a number, after all. Immer may be doing some proxy magic, but if they can't resolve something that simple, they wouldn't be working very well. (Edit: no difference) – RonLugge Nov 09 '19 at 00:12
  • @markerikson so having done some more experiments, instead of having a 'simple' test inside my app, I did a simple test with a clean test app. Looks like I'm actually looking at an interaction between some of the other packages in my app and immer -- and I have _no_ clue which one. I'm going to have to start from scratch and build up until I can define it, and then ask the relevant repo for help. – RonLugge Nov 09 '19 at 03:56
  • @markerikson thanks for the attempt at help you've given me, but I've decided this project is cursed. I just spent (way too much) time experimenting, and eventually I copied effectively the entire app over into the test app. The test app -- with absolutely identical code -- works fine, while the development app doesn't. Clearly something _very_ odd is going on. – RonLugge Nov 09 '19 at 05:06

1 Answers1

1

Turns out the problem wasn't in the code I was sharing, it was way over to the side when I was setting up my initial state. Electron was manipulating the data I sent back and forth via getState(), adding getter & setter methods. Those getter & setter methods were (quite rightly) triggering this error.

const initialState = remote.getGlobal('state');
console.log("initial state: ", initialState);
const store = CreateStore({initialState:{...initialState}, main: false})

Expected log output: { counter: { value: 1 } ...rest}, but actual output was { counter: {value: 1, getValue: function(), setValue: function() }, getCounter: function(), setCounter: function(), ...rest.

Woops. Now I just need to 'clean' my state up, since apparently state storage somehow persists this failure. And then figure out how to strip the (nested!) getters/setters. Ugh.

Edit: Rather than stripping the getters / setters, I just needed to use the built-in getInitialStateRenderer from electron-redux. So change the above code to:

const initialState = getInitiateStateRenderer() const store = CreateStore({ initialState: initialState, main: false })

zastrowm
  • 8,017
  • 3
  • 43
  • 63
RonLugge
  • 5,086
  • 5
  • 33
  • 61