@@ -175,6 +175,61 @@ const NameInputView = Component.make("NameInput")(function* () {
|
|||||||
the setter writes through the Lens, so every other component subscribed to the
|
the setter writes through the Lens, so every other component subscribed to the
|
||||||
same Lens sees the update.
|
same Lens sees the update.
|
||||||
|
|
||||||
|
## Focused Lenses
|
||||||
|
|
||||||
|
Use focused Lenses when a component should work with one part of a larger state
|
||||||
|
object. A focused Lens is still a Lens, so it can be read with
|
||||||
|
`Subscribable.useAll` or used with `Lens.useState` when React needs a
|
||||||
|
read/write tuple.
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { Effect, SubscriptionRef } from "effect"
|
||||||
|
import { Component, Lens, Subscribable } from "effect-fc"
|
||||||
|
|
||||||
|
interface UserProfile {
|
||||||
|
readonly name: string
|
||||||
|
readonly email: string
|
||||||
|
readonly role: string
|
||||||
|
}
|
||||||
|
|
||||||
|
class ProfileState extends Effect.Service<ProfileState>()("ProfileState", {
|
||||||
|
effect: Effect.gen(function* () {
|
||||||
|
const profile = Lens.fromSubscriptionRef(
|
||||||
|
yield* SubscriptionRef.make<UserProfile>({
|
||||||
|
name: "",
|
||||||
|
email: "",
|
||||||
|
role: "reader",
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
const name = Lens.focusObjectOn(profile, "name")
|
||||||
|
const role = Lens.focusObjectOn(profile, "role")
|
||||||
|
|
||||||
|
return { profile, name, role } as const
|
||||||
|
}),
|
||||||
|
}) {}
|
||||||
|
|
||||||
|
const ProfileNameView = Component.make("ProfileName")(function* () {
|
||||||
|
const state = yield* ProfileState
|
||||||
|
const [name, setName] = yield* Lens.useState(state.name)
|
||||||
|
const [role] = yield* Subscribable.useAll([state.role])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<label>
|
||||||
|
Name
|
||||||
|
<input
|
||||||
|
value={name}
|
||||||
|
onChange={(event) => setName(event.currentTarget.value)}
|
||||||
|
/>
|
||||||
|
<span>Role: {role}</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
|
||||||
|
`Subscribable.useAll` path.
|
||||||
|
|
||||||
For focusing into nested state, deriving lenses, custom write behavior, and the
|
For focusing into nested state, deriving lenses, custom write behavior, and the
|
||||||
complete API, refer to the
|
complete API, refer to the
|
||||||
[`effect-lens` documentation](https://github.com/Thiladev/effect-lens).
|
[`effect-lens` documentation](https://github.com/Thiladev/effect-lens).
|
||||||
|
|||||||
Reference in New Issue
Block a user