Fix
Lint / lint (push) Successful in 47s

This commit is contained in:
Julien Valverdé
2026-06-09 10:42:42 +02:00
parent 8303c1f70e
commit 74a8e3a102
+17 -41
View File
@@ -89,11 +89,11 @@ Use `Component.make` when you want automatic tracing spans, or
`Component.makeUntraced` when you only want the component behavior. This creates `Component.makeUntraced` when you only want the component behavior. This creates
an Effect-FC component, not a plain React component yet. an Effect-FC component, not a plain React component yet.
```tsx title="src/HelloEffect.tsx" ```tsx title="src/HelloView.tsx"
import { Effect } from "effect" import { Effect } from "effect"
import { Component } from "effect-fc" import { Component } from "effect-fc"
export const HelloEffect = Component.make("HelloEffect")(function* (props: { export const HelloView = Component.make("HelloView")(function* (props: {
readonly name: string readonly name: string
}) { }) {
const message = yield* Effect.succeed(`Hello, ${props.name}`) const message = yield* Effect.succeed(`Hello, ${props.name}`)
@@ -102,7 +102,7 @@ export const HelloEffect = Component.make("HelloEffect")(function* (props: {
}) })
``` ```
At this point `HelloEffect` can yield Effects, services, and scoped lifecycle At this point `HelloView` can yield Effects, services, and scoped lifecycle
work, but React cannot render it directly. work, but React cannot render it directly.
## Apply A Runtime ## Apply A Runtime
@@ -112,10 +112,10 @@ to become a regular React function component.
```tsx title="src/Hello.tsx" ```tsx title="src/Hello.tsx"
import { Component } from "effect-fc" import { Component } from "effect-fc"
import { HelloEffect } from "./HelloEffect" import { HelloView } from "./HelloView"
import { runtime } from "./runtime" import { runtime } from "./runtime"
export const Hello = HelloEffect.pipe( export const Hello = HelloView.pipe(
Component.withRuntime(runtime.context), Component.withRuntime(runtime.context),
) )
``` ```
@@ -136,13 +136,13 @@ Inside an Effect-FC component, other Effect-FC components are available through
their `.use` effect. Yield `.use` to get a React component for the current their `.use` effect. Yield `.use` to get a React component for the current
runtime context, then render it like JSX. runtime context, then render it like JSX.
```tsx title="src/GreetingCardEffect.tsx" ```tsx title="src/GreetingCardView.tsx"
import { Component } from "effect-fc" import { Component } from "effect-fc"
import { HelloEffect } from "./HelloEffect" import { HelloView } from "./HelloView"
export const GreetingCardEffect = Component.make("GreetingCard")( export const GreetingCardView = Component.make("GreetingCard")(
function* () { function* () {
const Hello = yield* HelloEffect.use const Hello = yield* HelloView.use
return ( return (
<section> <section>
@@ -159,10 +159,10 @@ normal React component again:
```tsx title="src/GreetingCard.tsx" ```tsx title="src/GreetingCard.tsx"
import { Component } from "effect-fc" import { Component } from "effect-fc"
import { GreetingCardEffect } from "./GreetingCardEffect" import { GreetingCardView } from "./GreetingCardView"
import { runtime } from "./runtime" import { runtime } from "./runtime"
export const GreetingCard = GreetingCardEffect.pipe( export const GreetingCard = GreetingCardView.pipe(
Component.withRuntime(runtime.context), Component.withRuntime(runtime.context),
) )
``` ```
@@ -177,11 +177,11 @@ The component scope is created when React mounts the component and closes when
React unmounts it. When the scope closes, Effect runs the finalizers registered React unmounts it. When the scope closes, Effect runs the finalizers registered
inside that scope. inside that scope.
```tsx title="src/MountedMessageEffect.tsx" ```tsx title="src/MountedMessageView.tsx"
import { Console, Effect } from "effect" import { Console, Effect } from "effect"
import { Component } from "effect-fc" import { Component } from "effect-fc"
export const MountedMessageEffect = Component.make("MountedMessage")( export const MountedMessageView = Component.make("MountedMessage")(
function* () { function* () {
const message = yield* Component.useOnMount(() => const message = yield* Component.useOnMount(() =>
Effect.gen(function* () { Effect.gen(function* () {
@@ -207,7 +207,7 @@ work should be recreated when dependencies change.
import { Console, Effect } from "effect" import { Console, Effect } from "effect"
import { Component } from "effect-fc" import { Component } from "effect-fc"
const UserPanelEffect = Component.make("UserPanel")( const UserPanelView = Component.make("UserPanel")(
function* (props: { readonly userId: string }) { function* (props: { readonly userId: string }) {
const user = yield* Component.useOnChange( const user = yield* Component.useOnChange(
() => () =>
@@ -307,7 +307,7 @@ including React hooks, refs, event handlers, context, and JSX composition.
import { Component } from "effect-fc" import { Component } from "effect-fc"
import * as React from "react" import * as React from "react"
const CounterEffect = Component.make("Counter")(function* () { const CounterView = Component.make("Counter")(function* () {
const [count, setCount] = React.useState(0) const [count, setCount] = React.useState(0)
const buttonRef = React.useRef<HTMLButtonElement>(null) const buttonRef = React.useRef<HTMLButtonElement>(null)
@@ -362,7 +362,7 @@ import { Component } from "effect-fc"
import { runtime } from "./runtime" import { runtime } from "./runtime"
import { GreetingService } from "./services" import { GreetingService } from "./services"
const GreetingEffect = Component.make("Greeting")(function* (props: { const GreetingView = Component.make("Greeting")(function* (props: {
readonly name: string readonly name: string
}) { }) {
const greeting = yield* GreetingService const greeting = yield* GreetingService
@@ -370,35 +370,11 @@ const GreetingEffect = Component.make("Greeting")(function* (props: {
return <p>{greeting.greet(props.name)}</p> return <p>{greeting.greet(props.name)}</p>
}) })
export const Greeting = GreetingEffect.pipe( export const Greeting = GreetingView.pipe(
Component.withRuntime(runtime.context), Component.withRuntime(runtime.context),
) )
``` ```
## Mount And Cleanup Effects
Use `Component.useOnMount` for scoped work that should start when the component
mounts and finalize when it unmounts.
```tsx
import { Console, Effect } from "effect"
import { Component } from "effect-fc"
const Mounted = Component.make("Mounted")(function* () {
yield* Component.useOnMount(() =>
Effect.gen(function* () {
yield* Console.log("Mounted")
yield* Effect.addFinalizer(() => Console.log("Unmounted"))
}),
)
return <p>Open the console, then unmount me.</p>
})
```
Finalizers are tied to the component scope, so this is the right place for
subscriptions, resources, and other lifecycle-bound Effects.
## Where To Go Next ## Where To Go Next
Once the runtime and component boundary are in place, the rest of the library Once the runtime and component boundary are in place, the rest of the library