Since all the fundamental constructs like Units, Actions, Systems, and Clusters are Observable, it makes sense that we create a custom Hook to easily bind their value to a component's local state. useObservable
is much simpler and ergonomic to use than useUnit.
import { useState, useEffect } from "react";import { Observable } from "rxjs";export type ObservableValueType<T> = T extends Observable<infer X> ? X : never;export function useObservable<U extends Observable<any>>($: U) {type T = ObservableValueType<U>;const [value, setValue] = useState<T>();useEffect(() => {const subscription = $.subscribe(setValue);return () => subscription.unsubscribe();}, [$]);return value;}
import { useState, useEffect } from "react";import { Observable } from "rxjs";export function useObservable(observable) {const [value, setValue] = useState();useEffect(() => {const subscription = observable.subscribe(setValue);return () => subscription.unsubscribe();}, [observable]);return value;}
// create a Unit or System, Cluster, Actionconst listUnit = new ListUnit({initialValue: ['🤯']});// a simple componentfunction Visualizer() {const value = useObservable(listUnit);return <span>{value}</span>;}// it'll render this immediately and will render any future values🤯
StackBlitz example that shares a Unit among multiple components.
Simple Counter example.
See this for usage in combination with AsyncSystem.