From 7cc0a68170578a0863dab3ce49ca2e3ad08eaa20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Tue, 1 Jul 2025 00:23:45 +0200 Subject: [PATCH] useMemoLayer --- packages/effect-components/src/ReactHook.ts | 15 ++++++++++++++- .../example/src/routes/effect-component-tests.tsx | 8 +------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/packages/effect-components/src/ReactHook.ts b/packages/effect-components/src/ReactHook.ts index befe806..87d4072 100644 --- a/packages/effect-components/src/ReactHook.ts +++ b/packages/effect-components/src/ReactHook.ts @@ -1,4 +1,4 @@ -import { Effect, ExecutionStrategy, Exit, pipe, Runtime, Scope, Stream, SubscriptionRef } from "effect" +import { type Context, Effect, ExecutionStrategy, Exit, type Layer, pipe, Runtime, Scope, Stream, SubscriptionRef } from "effect" import * as React from "react" @@ -29,6 +29,19 @@ export const useOnce: { return yield* useMemo(factory, []) }) +export const useMemoLayer: { + ( + layer: Layer.Layer + ): Effect.Effect, never, RIn> +} = Effect.fnUntraced(function* ( + layer: Layer.Layer +) { + const runtime = yield* Effect.runtime() + return React.useMemo(() => Runtime.runSync(runtime)( + Effect.provide(Effect.context(), layer) + ), [layer]) +}) + export const useEffect: { ( effect: () => Effect.Effect, diff --git a/packages/example/src/routes/effect-component-tests.tsx b/packages/example/src/routes/effect-component-tests.tsx index fb95aae..a506451 100644 --- a/packages/example/src/routes/effect-component-tests.tsx +++ b/packages/example/src/routes/effect-component-tests.tsx @@ -2,7 +2,6 @@ import { Box, TextField } from "@radix-ui/themes" import { createFileRoute } from "@tanstack/react-router" import { Console, Effect, Layer, pipe, Ref, Runtime, SubscriptionRef } from "effect" import { ReactComponent, ReactHook, ReactManagedRuntime } from "effect-components" -import * as React from "react" const LogLive = Layer.scopedDiscard(Effect.acquireRelease( @@ -52,12 +51,7 @@ const MyRoute = pipe( {yield* ReactComponent.use(MyTestComponent, C => ).pipe( - Effect.provide(React.useMemo(() => - Effect.context().pipe( - Effect.provide(SubService.Default), - Runtime.runSync(runtime), - ), - [])) + Effect.provide(yield* ReactHook.useMemoLayer(SubService.Default)) )} }),