Skip to content

Commit 792344c

Browse files
committed
final touches
1 parent e6bd55e commit 792344c

File tree

15 files changed

+129
-57
lines changed

15 files changed

+129
-57
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import asyncio
2+
3+
from idom import component, html, run, use_state
4+
5+
6+
@component
7+
def Counter():
8+
number, set_number = use_state(0)
9+
10+
async def handle_click(event):
11+
await asyncio.sleep(3)
12+
set_number(lambda old_number: old_number + 1)
13+
14+
return html.div(
15+
html.h1(number),
16+
html.button({"onClick": handle_click}, "Increment"),
17+
)
18+
19+
20+
run(Counter)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import asyncio
2+
3+
from idom import component, html, run, use_state
4+
5+
6+
@component
7+
def Counter():
8+
number, set_number = use_state(0)
9+
10+
async def handle_click(event):
11+
await asyncio.sleep(3)
12+
set_number(number + 1)
13+
14+
return html.div(
15+
html.h1(number),
16+
html.button({"onClick": handle_click}, "Increment"),
17+
)
18+
19+
20+
run(Counter)

docs/source/adding-interactivity/_examples/set_color_3_times.py

+10-2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,16 @@ def handle_click(event):
1010
set_color("pink")
1111
set_color("blue")
1212

13-
return html.button(
14-
{"onClick": handle_click, "style": {"backgroundColor": color}}, "Set Color"
13+
def handle_reset(event):
14+
set_color("gray")
15+
16+
return html.div(
17+
html.button(
18+
{"onClick": handle_click, "style": {"backgroundColor": color}}, "Set Color"
19+
),
20+
html.button(
21+
{"onClick": handle_reset, "style": {"backgroundColor": color}}, "Reset"
22+
),
1523
)
1624

1725

docs/source/adding-interactivity/index.rst

+27-7
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,15 @@ Adding Interactivity
3636
:link: state-as-a-snapshot
3737
:link-type: doc
3838

39-
Learn why IDOM does not change component state the moment it is set, but
40-
instead schedules a re-render.
39+
Learn why state updates schedules a re-render, instead of being applied
40+
immediately.
4141

4242
.. grid-item-card:: :octicon:`versions` Multiple State Updates
4343
:link: multiple-state-updates
4444
:link-type: doc
4545

46-
Under construction 🚧
46+
Learn how updates to a components state can be batched, or applied
47+
incrementally.
4748

4849
.. grid-item-card:: :octicon:`issue-opened` Dangers of Mutability
4950
:link: dangers-of-mutability
@@ -147,12 +148,31 @@ snapshot.
147148
:octicon:`book` Read More
148149
^^^^^^^^^^^^^^^^^^^^^^^^^
149150

150-
Learn why IDOM does not change component state the moment it is set, but instead
151-
schedules a re-render.
151+
Learn why state updates schedules a re-render, instead of being applied immediately.
152152

153153

154154
Section 4: Multiple State Updates
155-
------------------------------------
155+
---------------------------------
156+
157+
As we saw in an earlier example, :ref:`setting state triggers renders`. In other words,
158+
changes to state only take effect in the next render, not in the current one. Further,
159+
changes to state are batched, calling a particular state setter 3 times won't trigger 3
160+
renders, it will only trigger 1. This means that multiple state assignments are batched
161+
- so long as the event handler is synchronous (i.e. the event handler is not an
162+
``async`` function), IDOM waits until all the code in an event handler has run before
163+
processing state and starting the next render:
164+
165+
.. idom:: _examples/set_color_3_times
166+
167+
Sometimes though, you need to update a state variable more than once before the next
168+
render. In these cases, instead of having updates batched, you instead want them to be
169+
applied incrementally. That is, the next update can be made to depend on the prior one.
170+
To accomplish this, instead of passing the next state value directly (e.g.
171+
``set_state(new_state)``), we may pass an **"updater function"** of the form
172+
``compute_new_state(old_state)`` to the state setter (e.g.
173+
``set_state(compute_new_state)``):
174+
175+
.. idom:: _examples/set_state_function
156176

157177
.. card::
158178
:link: multiple-state-updates
@@ -161,7 +181,7 @@ Section 4: Multiple State Updates
161181
:octicon:`book` Read More
162182
^^^^^^^^^^^^^^^^^^^^^^^^^
163183

164-
...
184+
Learn how updates to a components state can be batched, or applied incrementally.
165185

166186

167187
Section 5: Dangers of Mutability

docs/source/adding-interactivity/multiple-state-updates.rst

+15-22
Original file line numberDiff line numberDiff line change
@@ -88,29 +88,22 @@ this is functionally equivalent to the following:
8888
8989
set_number(increment(increment(increment(number))))
9090
91-
So why might you want to do this? Well, in this case, we're using the same function on
92-
each call to ``set_number``, but what if you had more function. Perhaps you might want
93-
to do introduce ``squared`` or ``decrement`` functions:
91+
So why might you want to do this? Why not just compute ``set_number(number + 3)`` from
92+
the start? The easiest way to explain the use case is with an example. Imagine that we
93+
introduced a delay before ``set_number(number + 1)``. What would happen if we clicked
94+
the "Increment" button more than once before the delay in the first triggered event
95+
completed?
9496

95-
.. code-block::
96-
97-
set_number(increment)
98-
set_number(squared)
99-
set_number(decrement)
100-
101-
Which would equate to:
102-
103-
.. code-block::
97+
.. idom:: _examples/delay_before_set_count
10498

105-
set_number(decrement(squared(increment(number))))
99+
From an :ref:`earlier lesson <State And Delayed Reactions>`, we learned that introducing
100+
delays do not change the fact that state variables do not change until the next render.
101+
As a result, despite clicking many times before the delay completes, the ``number`` only
102+
increments by one. To solve this we can use updater functions:
106103

107-
This example also presents a scenario with much simpler state. Consider an example where
108-
the state is more complex. In the scenario below, we need to represent and manipulate
109-
state that represents the position of a character in a scene. Then imagine that we want
110-
to allow the user to queue their actions and then apply them all at once. The simplest
111-
way to do this is to factor out the functions which manualuate this state into
112-
functions, add them to an ``actions`` queue when the user requests, and finally, once
113-
the user clicks "Apply Actions", iterator over the ``actions`` and call ``set_position``
114-
with each action function:
104+
.. idom:: _examples/delay_before_count_updater
115105

116-
.. idom:: _examples/character_movement
106+
Now when you click the "Increment" button, each click, though delayed, corresponds to
107+
``number`` being increased. This is because the ``old_number`` in the updater function
108+
uses the value which was assigned by the last call to ``set_number`` rather than relying
109+
in the static ``number`` state variable.

docs/source/conf.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
# ones.
4949
extensions = [
5050
"sphinx.ext.autodoc",
51-
"sphinx.ext.intersphinx",
51+
# "sphinx.ext.intersphinx",
5252
"sphinx.ext.coverage",
5353
"sphinx.ext.viewcode",
5454
"sphinx.ext.napoleon",
@@ -65,7 +65,7 @@
6565
"idom_view",
6666
"patched_html_translator",
6767
"idom_example",
68-
"build_custom_js",
68+
# "build_custom_js",
6969
]
7070

7171
# Add any paths that contain templates here, relative to this directory.

docs/source/escape-hatches/class-components.rst

+5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
Class Components 🚧
44
===================
55

6+
.. warning::
7+
8+
This feature has not been implemented `yet
9+
<https://github.com/idom-team/idom/pull/518>`__.
10+
611
.. note::
712

813
Under construction 🚧

docs/source/escape-hatches/index.rst

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
.. _Escape Hatches:
22

3-
Escape Hatches 🚧
4-
=================
3+
Escape Hatches
4+
==============
55

66
.. toctree::
77
:hidden:

docs/source/index.rst

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
.. note::
2+
3+
This documentation is still under construction 🚧. We welcome your `feedback
4+
<https://github.com/idom-team/idom/discussions>`__!
5+
6+
17
IDOM
28
====
39

@@ -156,8 +162,7 @@ other :ref:`later <managing state>`).
156162
:octicon:`book` Read More
157163
^^^^^^^^^^^^^^^^^^^^^^^^^
158164

159-
Under construction 🚧
160-
165+
Learn how user interfaces can be made to respond to user interaction in real-time.
161166

162167

163168
Chapter 4 - :ref:`Managing State`

docs/source/managing-state/index.rst

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
.. _Managing State:
22

3-
Managing State 🚧
4-
=================
3+
Managing State
4+
==============
55

66
.. toctree::
77
:hidden:

docs/source/adding-interactivity/_examples/character_movement/app.py renamed to docs/source/reference-material/_examples/character_movement/app.py

+6-16
Original file line numberDiff line numberDiff line change
@@ -33,17 +33,8 @@ def translate(x=0, y=0):
3333

3434
@component
3535
def Scene():
36-
actions, set_actions = use_state(())
3736
position, set_position = use_state(Position(100, 100, 0))
3837

39-
def handle_apply_actions(event):
40-
for act_function in actions:
41-
set_position(act_function)
42-
set_actions(())
43-
44-
def make_action_handler(act_function):
45-
return lambda event: set_actions(actions + (act_function,))
46-
4738
return html.div(
4839
{"style": {"width": "225px"}},
4940
html.div(
@@ -67,13 +58,12 @@ def make_action_handler(act_function):
6758
},
6859
),
6960
),
70-
html.button({"onClick": make_action_handler(translate(x=-10))}, "Move Left"),
71-
html.button({"onClick": make_action_handler(translate(x=10))}, "Move Right"),
72-
html.button({"onClick": make_action_handler(translate(y=-10))}, "Move Up"),
73-
html.button({"onClick": make_action_handler(translate(y=10))}, "Move Down"),
74-
html.button({"onClick": make_action_handler(rotate(-30))}, "Rotate Left"),
75-
html.button({"onClick": make_action_handler(rotate(30))}, "Rotate Right"),
76-
html.button({"onClick": handle_apply_actions}, html.b("Apply Actions")),
61+
html.button({"onClick": lambda e: set_position(translate(x=-10))}, "Move Left"),
62+
html.button({"onClick": lambda e: set_position(translate(x=10))}, "Move Right"),
63+
html.button({"onClick": lambda e: set_position(translate(y=-10))}, "Move Up"),
64+
html.button({"onClick": lambda e: set_position(translate(y=10))}, "Move Down"),
65+
html.button({"onClick": lambda e: set_position(rotate(-30))}, "Rotate Left"),
66+
html.button({"onClick": lambda e: set_position(rotate(30))}, "Rotate Right"),
7767
)
7868

7969

docs/source/reference-material/gallery.rst

+7
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,13 @@ Try typing in the text box and pressing 'Enter' 📋
2626
:result-is-default-tab:
2727

2828

29+
Simple Image Movement
30+
---------------------
31+
32+
.. idom:: _examples/character_movement
33+
:result-is-default-tab:
34+
35+
2936
The Game Snake
3037
--------------
3138

docs/source/reference-material/index.rst

+4
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,7 @@ Reference Material
1111
/_autogen/user-apis
1212
specifications
1313
faq
14+
15+
.. note::
16+
17+
Under construction 🚧

docs/source/understanding-idom/index.rst

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
.. _Understanding IDOM:
22

3-
Understanding IDOM 🚧
4-
=====================
3+
Understanding IDOM
4+
==================
55

66
.. toctree::
77
:hidden:

0 commit comments

Comments
 (0)