Finalize the Effect View rename and refresh docs, examples, and tooling #59
@@ -228,11 +228,7 @@ interface UserProfile {
|
||||
|
||||
class ProfileState extends Context.Service<
|
||||
ProfileState,
|
||||
{
|
||||
readonly profile: Lens.Lens<UserProfile>
|
||||
readonly name: Lens.Lens<string>
|
||||
readonly role: Lens.Lens<string>
|
||||
}
|
||||
{ readonly profile: Lens.Lens<UserProfile> }
|
||||
>()("ProfileState") {
|
||||
static readonly layer = Layer.effect(
|
||||
ProfileState,
|
||||
@@ -249,18 +245,28 @@ class ProfileState extends Context.Service<
|
||||
},
|
||||
}),
|
||||
)
|
||||
const name = Lens.focusObjectOn(profile, "name")
|
||||
const role = Lens.focusObjectOn(profile, "role")
|
||||
|
||||
return { profile, name, role } as const
|
||||
return { profile } as const
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
const ProfileNameView = Component.make("ProfileName")(function*() {
|
||||
const state = yield* ProfileState
|
||||
const [name, setName] = yield* Lens.useState(state.name)
|
||||
const [role] = yield* View.useAll([state.role])
|
||||
const [nameLens, roleLens, cityLens] = yield* Component.useOnMount(() =>
|
||||
Effect.succeed([
|
||||
Lens.focusObjectOn(state.profile, "name"),
|
||||
Lens.focusObjectOn(state.profile, "role"),
|
||||
state.profile.pipe(
|
||||
Lens.focusObjectOn("contact"),
|
||||
Lens.focusObjectOn("address"),
|
||||
Lens.focusObjectOn("city"),
|
||||
),
|
||||
] as const),
|
||||
)
|
||||
|
||||
const [name, setName] = yield* Lens.useState(nameLens)
|
||||
const [role, city] = yield* View.useAll([roleLens, cityLens])
|
||||
|
||||
return (
|
||||
<label>
|
||||
@@ -270,27 +276,21 @@ const ProfileNameView = Component.make("ProfileName")(function*() {
|
||||
onChange={(event) => setName(event.currentTarget.value)}
|
||||
/>
|
||||
<span>Role: {role}</span>
|
||||
<span>City: {city}</span>
|
||||
</label>
|
||||
)
|
||||
})
|
||||
```
|
||||
|
||||
Updating the focused `name` Lens through `Lens.useState` updates the parent
|
||||
`profile` Lens. The focused `role` Lens is only read, so it stays on the simpler
|
||||
`View.useAll` path.
|
||||
The service owns only the root `profile` Lens. The component chooses the fields
|
||||
it needs, creates those focused Lenses once in `Component.useOnMount`, and
|
||||
subscribes only to them. Updating `nameLens` through `Lens.useState` still
|
||||
updates the parent `profile` Lens.
|
||||
|
||||
Lens focus helpers have a dual API. They can be called in data-first form, such
|
||||
as `Lens.focusObjectOn(profile, "name")`, or in curried form with only the key
|
||||
or index. The curried form composes naturally with `pipe` for deeper paths:
|
||||
|
||||
```tsx
|
||||
// profileLens is a Lens.Lens<UserProfile>
|
||||
const cityLens = profileLens.pipe(
|
||||
Lens.focusObjectOn("contact"),
|
||||
Lens.focusObjectOn("address"),
|
||||
Lens.focusObjectOn("city"),
|
||||
)
|
||||
```
|
||||
or index. The `cityLens` above uses the curried form with `pipe` to focus through
|
||||
a deeper path without storing intermediate Lenses.
|
||||
|
||||
For focusing into nested state, deriving lenses, custom write behavior, and the
|
||||
complete API, refer to the
|
||||
|
||||
Reference in New Issue
Block a user