# Different kinds of reactivity Looms: - https://www.loom.com/share/9d722f70ad77435d838742e38b17b613 - direct - composed - computed - effect - resource ## Direct A straight up binding to a framework primitive - autoregistration ```typescript const [firstName] = useSignal('Misko'); --- <span>{firstName()}</span> ``` ## Composed A value which is computed through helper function, but it is not cached. - no-additional magic - auto-registration ```typescript const [firstName] = useSignal('Misko'); const [lastName] = useSignal('Hevery'); const fullName = () => firstName() + ' ' + lastName();  <span>{fullName()}</span> ``` ## Computed A value which is lazy computed and cached, so that multiple invocation return the same instance. - memoization - synchronous - lazy computation on read ```typescript const [firstName] = useSignal('Misko'); const [lastName] = useSignal('Hevery'); const fullName = useComputed(() => firstName() + ' ' + lastName()); --- <span>{fullName()}</span> ``` ## watch (async computed) Async computed??? - async - eager on input change - preemtable (cleanup) - serial execution (serial execution of effects, non-parallel) - before rendering - both server/client ## clientEffect Runs eagerly on change, can by async and has cleanup; preemtable - async - eager on input - preemtable (cleanup) - serial execution (serial execution of effects, non-parallel) - after rendering - client only (SSR has no DOM) ```typescript const [firstName] = useSignal('Misko'); const [lastName] = useSignal('Hevery'); const [fullName, setFullName] = useSignal(); useEffect(async ({track}) => { track(firstName, lastName); await delay(10); setFullName(firstName() + ' ' + lastName()); return () => null; // This is wrong! It is too late! }); --- <span>{fullName()}</span> ``` ## resource Runs eagerly on change, can by async and has cleanup, returns value - async - eager - preemtable (cleanup) - non-serial execution (concurrent execution of resource) - pure ```typescript const [firstName] = useSignal('Misko'); const [lastName] = useSignal('Hevery'); const [fullName] = useResource(async ({track, cleanup}) => { track(firstName, lastName); cleanup(() => void); await delay(100); return firstName() + ' ' + lastName() }); --- <span>{fullName()}</span> ``` --- | type | eval | async | return | cleanup | |-----------|--------|--------|--------|--------| | direct | - | sync | value | - | composed | eager | sync | value | - | computed | lazy | sync | value | - | effect | eager | async | - | yes | resource | eager | async | promise | yes --- # Rendering 1. state change invalidates component/watch Revalidation: 1. if watches: Run watches and await 2. if resources: Run resource in paralel 3. if jsx: Render (execute JSX) 4. if queue: Flush DOM write queue on rAF 5. If effects: Run effects PS: - In SSR 4/5 does not happen - 2/3/4 con