hyperapp-logger icon indicating copy to clipboard operation
hyperapp-logger copied to clipboard

Incorrect next state with actions updating slices of state

Open Beaglefoot opened this issue 6 years ago • 2 comments

Imagine the following scenario:

const state = {
  counters: {
    count1: 1,
    count2: 2,
    count3: 3
  }
};

const actions = {
  counters: {
    inc1: () => ({ count1 }) => ({ count1: count1 + 1 })
  }
};

Let's run inc1() action and here's what we see...

prev state:

{
  count1: 1,
  count2: 2,
  count3: 3
}

next state:

{ count1: 2 }

What's expected next state:

{
  count1: 2,
  count2: 2,
  count3: 3
}

Right now logger simply returns the result of an action, and I strongly believe that it should return merged slice of a state. Here's an illustration

BTW, thanks for logger!

Beaglefoot avatar Feb 27 '18 19:02 Beaglefoot

The root cause, of course, is that Hyperapp performs a shallow merge of your action result/return with the existing state in the same slice and finally returns only the partial state that was merged in to the caller. I can think of three ways of solving this:

  1. Update the default logger message and documentation to reflect that we are seeing the action result instead of the next state.
  2. Actually perform the same merge as Hyperapp and use the entire next state slice value. This will be duplicating a very small bit of code already in Hyperapp, but it's not likely to change much.
  3. Petition Hyperapp core to return the merged new state slice instead of just the action result from actions that update the state, and this works with no change at all. This would be a breaking change and not very likely to be accepted.

okwolf avatar Mar 01 '18 04:03 okwolf

~~There is another solution, check #21~~

Well, I played around with this a little bit and it seems that some actions get lost when asynchrony is involved. Please ignore...

Beaglefoot avatar Mar 01 '18 12:03 Beaglefoot