Async access to current state, outside actions
See original GitHub issueAbstract / TL;DR; When you try to access the state asynchronously in the view, like in onbeforeremove
or in setTimeout
called in event handlers, the state will be stale. There are workarounds, but they are not ideal.
The long version:
If you define a function inside the view, which will be called at a later time, that function will not have access to the current state at the time it is called. If you try, the state you get will be stale. This means, for example, you cannot rely on state inside onbeforeremove
handlers, or in setTimeout
s called in event handlers. For a concrete demonstration of this problem, see this example of a carousel:
https://codepen.io/zaceno/pen/WdrZdK
I’m using hyperapp-transitions in order to have a not too contrived, but still short, example. All you need to know is that
transitions.exit
runs the transition in theonbeforeremove
handler.- The function passed to the
css
prop is called at the time of the transition, in this case to determine the direction to exit/enter. (Since it depends on where the user clicked)
Notice when you click the buttons of the carousel that as long as you times in a row, the new images slide in the same direction as the old images slide out. But every time you switch directions, the image leaves according to the old direction, while the new image slides in from the correct direction.
The explanation for this, is that the exit transition (and hence onbeforeremove
handler, has the old state in it’s closure) – it hasn’t ever even seen the new state, since it’s no longer in the vtree (that’s why its being removed).
There are, of course, workarounds…
One way to solve it, would be to keep an up to date copy of the relevant state somewhere, accessible by the functions that need it. That’s how I solved it for the caruousel example in this codepen:
https://codepen.io/zaceno/pen/LeGQab?editors=0010
See especially lines 14, 32, 37, 38. Notice how now when you switch directions, it works as intended. This works for the occasional one off, but is obviously far from ideal.
Another solution is to use an action (since actions are special, and always have access to the current state when they’re called), relying on the fact that actions return their partial state. See:
https://codepen.io/zaceno/pen/ZvQrgE?editors=0010 (notice lines 14, 16, 22)
This solution is better than the previous, but also unsatisfying (for me at least). It’s annoying that simply accessing the state will cause an update and rerender.
Issue Analytics
- State:
- Created 6 years ago
- Comments:7 (7 by maintainers)
@zaceno
getState
does not cause a re-render.👍