Hooks#

Hooks introduce various features into stateless component() Elements.

Rules of Hooks#

Hooks are inspired by React Hooks, and follow the React Rules of Hooks:

The exact same Hooks must be called in exactly the same order on every call to a component() function.

  1. Only call Hooks
    • In the top level of a component() Element function.

    • In the body of a custom Hook.

  2. Never call Hooks
    • In a conditional statement.

    • In a loop.

__eq__ relation#

The __eq__ relation is important for all Hooks. It is used to decide when state has changed which determines when components need re-rendering. It is used to decide when dependencies have changed which determines when effects need re-running.

For the __eq__ relation to work properly, it must mean that if two objects are __eq__, then one can be substituted for the other. This relation is not true for many Python types, especially object types for which __eq__ defaults to identity.

Here is an example of a wrapper type for numpy arrays which implements __eq__ so that they can be used in Hooks:

T_Array_co = TypeVar("T_Array_co", bound=np.generic, covariant=True)

class Array(Generic[T_Array_co]):
    """Wrapper for numpy arrays for substitutional __eq__."""
    def __init__(self, np_array: npt.NDArray[T_Array_co]) -> None:
        super().__init__()
        self.np_array = np_array

    def __eq__(self, other: Array) -> bool:
        return numpy.array_equal(self.np_array, other.np_array, equal_nan=True)

Custom Hooks#

A “custom Hook” is just a function that calls other Hooks. For example, here is a custom Hook which runs an effect exactly once, without providing dependencies to trigger re-running the effect, and without running a cleanup function:

def use_effect_once(f):
    def f_wrapped():
        f()
        def no_cleanup():
              pass
        return no_cleanup
    use_effect(f_wrapped, 0)

Hooks#

use_state(initial_state)

Persistent mutable state Hook inside a edifice.component() function.

use_effect(setup[, dependencies])

Side-effect Hook inside a edifice.component() function.

use_effect_final(cleanup[, dependencies])

Side-effect Hook for when a edifice.component() unmounts.

use_async(fn_coroutine, dependencies)

Asynchronous side-effect Hook inside a edifice.component() function.

use_async_call(fn_coroutine)

Hook to call an async function from a non-async context.

use_ref()

Hook for creating a Reference inside a edifice.component() function.