I am getting some results I'm finding difficult to comprehend when I am calling actions from within an action, eg. the action setS1rS2 (on button S1rS2) compared to action setS1S2 in jsfiddle https://jsfiddle.net/WarwickGrigg/eo537smc/
Using latest hyperapp v 1.0.1. Excerpt below:
const actions = {
setS1: dt => (_, actions) => { return {s1: dt} }, // changes state
setS2: dt => (_, actions) => { return {s2: dt} }, // changes state
setS1S2: dt => (_, actions) => {
actions.setS1(dt); // changes state
actions.setS2(dt); // changes state
},
setS1rS2:dt => (_, actions) => {
actions.setS1(dt); // no effect (!)
return {s2: dt}; // changes state for s2
},
Results are different but even more confusing (for me) if I remove the '=> (_, actions)' action function wrapper. Is there something special about calling actions from within an action?
@warwickgrigg Nice find! I introduced this bug here.
We need to compute the substate/slice again before merging with the state.
I'll fix it over the weekend. 馃憤
Okay, I found the fix changing line 107 to:
if (data && data !== (slice = get(path, state)) && !data.then) {
repaint((state = set(path, copy(slice, data), state, {})))
}
The interesting part is:
slice = get(path, state)
that basically computes the slice afresh.
Thanks, Jorge. And thank you for hyperapp - very promising and elegant. I've created a jsfiddle fork here https://jsfiddle.net/WarwickGrigg/rqqzqb9n/ with the action functions omitting the => (_, actions) wrapper, annotating the results:
const actions = {
setS1: dt => { return {s1: dt} }, // changes state
setS2: dt => { return {s2: dt} }, // changes state
setS1S2: dt => {
actions.setS1(dt); // no effect
actions.setS2(dt); // no effect
},
setS1rS2:dt => {
actions.setS1(dt); // no effect (!)
return {s2: dt}; // changes state for s2
},
setS1cS2:dt => {
s1obj = actions.setS1(dt); // assume no effect (?), but returns obj
return Object.assign([], s1obj, {s2: dt}); // changes state`
@warwickgrigg Done! 馃挭
@warwickgrigg Published as 1.0.2! 馃帀
Turns out the fractals example was a victim of this bug, but it now works again.
But isn鈥檛 it good to never, ever rely on multiple synchronous state updates and merge them before returning something instead?
@infinnie What?
how i can use it now?
@maxbaluev use what?
Calling actions in actions, in the latest release 1.2.6 (or is it 1.2.9?) works as described in the docs.
myMultiAction: data => (state, actions) => {
actions.action1(data.foo)
actions.action2(data.bar)
}
Calling actions in actions won't work in V2. Instead you will have to compose the actions, like @infinnie suggested earlier in this thread.
Most helpful comment
Okay, I found the fix changing line 107 to:
The interesting part is:
that basically computes the slice afresh.