diff --git a/packages/docs/docs/getting-started.md b/packages/docs/docs/getting-started.md index cae6a2e..68c9d7f 100644 --- a/packages/docs/docs/getting-started.md +++ b/packages/docs/docs/getting-started.md @@ -183,29 +183,42 @@ import { Component } from "effect-fc" export const MountedMessageEffect = Component.make("MountedMessage")( function* () { - yield* Component.useOnMount(() => + const message = yield* Component.useOnMount(() => Effect.gen(function* () { yield* Console.log("MountedMessage mounted") yield* Effect.addFinalizer(() => Console.log("MountedMessage unmounted"), ) + + return "This value was loaded on mount." }), ) - return
This component owns an Effect scope.
+ return{message}
}, ) ``` Use `Component.useOnMount` for work that should run once for the component -instance. Use `Component.useOnChange` when the scoped work should be recreated -when dependencies change. +instance and return a cached value. Use `Component.useOnChange` when the scoped +work should be recreated when dependencies change. ```tsx +import { Console, Effect } from "effect" +import { Component } from "effect-fc" + const UserPanelEffect = Component.make("UserPanel")( function* (props: { readonly userId: string }) { const user = yield* Component.useOnChange( - () => fetchUser(props.userId), + () => + Effect.gen(function* () { + yield* Console.log(`Loading ${props.userId}`) + yield* Effect.addFinalizer(() => + Console.log(`Cleaning up ${props.userId}`), + ) + + return yield* fetchUser(props.userId) + }), [props.userId], ) @@ -214,8 +227,9 @@ const UserPanelEffect = Component.make("UserPanel")( ) ``` -In this example, changing `userId` closes the previous dependency scope before -creating a new one. Unlike `useOnMount`, `useOnChange` does not expose the +In this example, each `userId` gets its own scope. When `userId` changes, +Effect-FC closes the previous scope, runs its finalizers, and creates a new +scope for the next load. Unlike `useOnMount`, `useOnChange` does not expose the component's root scope directly. It creates and provides its own scope for that dependency window. Some other Effect-FC hooks follow the same pattern when they need a lifecycle that is narrower than the whole component instance.