01-atoms
Effect Atom reactivity — useAtomValue, Atom.make, React integration via @effect/atom-react
- License 许可
- MIT
- 最近更新
- 2026-05-31
- Stars
- ★ 0
- Forks
- 0
01 前言 Front Matter
- name
- 01-atoms
- license
- MIT
- description
- Effect Atom reactivity — useAtomValue, Atom.make, React integration via @effect/atom-react
- compatibility
- opencode
03 SKILL.md 正文
Effect Atom (Reactivity)
Package: effect/unstable/reactivity, @effect/atom-react
Version: effect@4.0.0-beta.41, @effect/atom-react@4.0.0-beta.41
Runtime setup
import { Layer } from "effect";
import { DevTools } from "effect/unstable/devtools";
import { FetchHttpClient } from "effect/unstable/http";
import { Atom } from "effect/unstable/reactivity";
// Static site — no RPC server, just FetchHttpClient
export const runtime = Atom.runtime(
FetchHttpClient.layer.pipe(
Layer.provideMerge(import.meta.env.VITE_ENABLE_DEVTOOLS === "true" ? DevTools.layer() : Layer.empty),
),
);
Atom types
// runtime.atom(Effect) — single-shot, loads once, reactive
export const benchmarkAtom = runtime.atom(
Effect.gen(function* () {
const client = yield* HttpClient.HttpClient;
const response = yield* client.get(url);
const body = yield* response.json;
return yield* Schema.decode(BenchmarkDataSchema)(body);
}),
);
// Type: Atom<AsyncResult<BenchmarkData, E>>
// runtime.fn(arg => Effect) — triggered/parameterized atom
export const searchAtom = runtime.fn((query: string) =>
Effect.gen(function* () {
const svc = yield* SearchService;
return yield* svc.search(query);
}),
);
// Type: AtomResultFn<string, SearchResult, E>
// runtime.atom(Stream) — streaming atom
export const streamAtom = runtime.atom(Stream.fromPubSub(myPubSub));
React hooks
import { useAtom, useAtomSet, useAtomValue } from "@effect/atom-react";
import { AsyncResult } from "effect/unstable/reactivity";
// Read-only
const result = useAtomValue(benchmarkAtom);
// Read + write (returns [value, setter])
const [result, trigger] = useAtom(searchAtom);
trigger("my query");
// Write-only
const trigger = useAtomSet(searchAtom);
trigger("my query");
AsyncResult pattern matching
import { AsyncResult } from "effect/unstable/reactivity";
// In a React component
const result = useAtomValue(benchmarkAtom);
return AsyncResult.match(result, {
onInitial: (_) => <Loading />,
onFailure: (e) => <Error message={String(e.cause)} />,
onSuccess: (s) => <Leaderboard data={s.value} />,
});
// getOrElse for a default
const data = AsyncResult.getOrElse(result, () => emptyBenchmarkData);
RegistryProvider — required in app root
// main.tsx — not needed explicitly when using Atom.runtime()
// The runtime() call registers itself globally.
// But for tests, wrap with RegistryProvider:
import { RegistryProvider } from "@effect/atom-react";
render(
<RegistryProvider>
<App />
</RegistryProvider>,
);
Key signatures from Atom.d.ts
// AtomRuntime.atom — wraps Effect or Stream → AsyncResult atom
runtime.atom(effect: Effect<A, E, R | AtomRegistry>): Atom<AsyncResult<A, E>>
// AtomRuntime.fn — triggered atom
runtime.fn(fn: (arg: Arg) => Effect<A, E, R | AtomRegistry>): AtomResultFn<Arg, A, E>
// AsyncResult states
type AsyncResult<A, E> = Initial<A, E> | Success<A, E> | Failure<A, E>
// Hooks
useAtomValue<A>(atom: Atom<A>): A
useAtom<R,W>(atom: Writable<R,W>): readonly [R, (value: W) => void]
useAtomSet<R,W>(atom: Writable<R,W>): (value: W) => void
04 同仓库更多 Skills
tmux-workflow
Development workflow with tmux — run dev servers, Storybook, and background processes in persistent sessions with live logs, while keeping OpenCode free for chat
04-anti-patterns
React anti-patterns to avoid — manual JSX repetition, useEffect misuse, reference instability, prop drilling, conditional hooks, and common performance traps
03-state-management
React state management patterns — lifting state, colocation, URL state, server state with TanStack Query, local state with useState/useReducer
02-component-composition
React component composition patterns — render props, compound components, list rendering with map, slot patterns, and layout primitives
01-fp-style
React functional programming style — pure components, hooks conventions, Effect Atom integration, and Tailwind patterns
react-animation
React animation with react/motion (Framer Motion) — declarative animations, gestures, layout animations, and performance best practices