An object which manages the "life cycle" of a layout component. The "life cycle" of a component is the set of events which occur from the time a component is first rendered until it is removed from the layout. The life cycle is ultimately driven by the layout itself, but components can
| 31 | |
| 32 | |
| 33 | class LifeCycleHook: |
| 34 | """An object which manages the "life cycle" of a layout component. |
| 35 | |
| 36 | The "life cycle" of a component is the set of events which occur from the time |
| 37 | a component is first rendered until it is removed from the layout. The life cycle |
| 38 | is ultimately driven by the layout itself, but components can "hook" into those |
| 39 | events to perform actions. Components gain access to their own life cycle hook |
| 40 | by calling :func:`current_hook`. They can then perform actions such as: |
| 41 | |
| 42 | 1. Adding state via :meth:`use_state` |
| 43 | 2. Adding effects via :meth:`add_effect` |
| 44 | 3. Setting or getting context providers via |
| 45 | :meth:`LifeCycleHook.set_context_provider` and |
| 46 | :meth:`get_context_provider` respectively. |
| 47 | |
| 48 | Components can request access to their own life cycle events and state through hooks |
| 49 | while :class:`~reactpy.core.proto.LayoutType` objects drive drive the life cycle |
| 50 | forward by triggering events and rendering view changes. |
| 51 | |
| 52 | Example: |
| 53 | |
| 54 | If removed from the complexities of a layout, a very simplified full life cycle |
| 55 | for a single component with no child components would look a bit like this: |
| 56 | |
| 57 | .. testcode:: |
| 58 | |
| 59 | from reactpy.core._life_cycle_hook import LifeCycleHook |
| 60 | from reactpy.core.hooks import current_hook |
| 61 | |
| 62 | # this function will come from a layout implementation |
| 63 | schedule_render = lambda: ... |
| 64 | |
| 65 | # --- start life cycle --- |
| 66 | |
| 67 | hook = LifeCycleHook(schedule_render) |
| 68 | |
| 69 | # --- start render cycle --- |
| 70 | |
| 71 | component = ... |
| 72 | await hook.affect_component_will_render(component) |
| 73 | try: |
| 74 | # render the component |
| 75 | ... |
| 76 | |
| 77 | # the component may access the current hook |
| 78 | assert current_hook() is hook |
| 79 | |
| 80 | # and save state or add effects |
| 81 | current_hook().use_state(lambda: ...) |
| 82 | |
| 83 | async def my_effect(stop_event): |
| 84 | ... |
| 85 | |
| 86 | current_hook().add_effect(my_effect) |
| 87 | finally: |
| 88 | await hook.affect_component_did_render() |
| 89 | |
| 90 | # This should only be called after the full set of changes associated with a |
no outgoing calls