or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

advanced-hooks.mdconcurrency-helpers.mdcore-hooks.mdfamily-patterns.mdindex.mdloadable-system.mdmemory-management.mdroot-provider.mdstate-definition.md
tile.json

tessl/npm-recoil

Recoil is an experimental state management framework for React applications that provides atoms and selectors for fine-grained reactivity.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/recoil@0.7.x

To install, run

npx @tessl/cli install tessl/npm-recoil@0.7.0

index.mddocs/

Recoil

Recoil is an experimental React state management framework that provides fine-grained reactivity through atoms (units of state) and selectors (derived state). It offers minimal boilerplate with automatic optimization, where components only re-render when specific state they depend on changes, and includes built-in support for asynchronous operations and concurrent React features.

Package Information

  • Package Name: recoil
  • Package Type: npm
  • Language: JavaScript with Flow types and TypeScript definitions
  • Installation: npm install recoil

Core Imports

import {
  RecoilRoot,
  atom,
  selector,
  useRecoilState,
  useRecoilValue,
  useSetRecoilState
} from "recoil";

CommonJS:

const {
  RecoilRoot,
  atom,
  selector,
  useRecoilState,
  useRecoilValue,
  useSetRecoilState
} = require("recoil");

Basic Usage

import React from 'react';
import {
  RecoilRoot,
  atom,
  selector,
  useRecoilState,
  useRecoilValue,
} from 'recoil';

// Define atoms (state)
const textState = atom({
  key: 'textState',
  default: '',
});

// Define selectors (derived state)
const charCountState = selector({
  key: 'charCountState',
  get: ({get}) => {
    const text = get(textState);
    return text.length;
  },
});

// Component using Recoil state
function TextInput() {
  const [text, setText] = useRecoilState(textState);
  return (
    <input
      value={text}
      onChange={(e) => setText(e.target.value)}
    />
  );
}

function CharacterCount() {
  const count = useRecoilValue(charCountState);
  return <div>Character Count: {count}</div>;
}

// App with RecoilRoot
function App() {
  return (
    <RecoilRoot>
      <TextInput />
      <CharacterCount />
    </RecoilRoot>
  );
}

Architecture

Recoil is built around several key concepts:

  • Atoms: Fundamental units of state that components can read from and write to
  • Selectors: Pure functions that transform state or compute derived state
  • RecoilRoot: Context provider that manages the state graph and subscriptions
  • Hooks: React hooks for reading and writing state with automatic subscriptions
  • State Graph: Directed graph where atoms are source nodes and selectors are derived nodes
  • Fine-grained Subscriptions: Components only re-render when specific state they depend on changes
  • Concurrent Mode Support: Built-in compatibility with React's concurrent features

Capabilities

Root Provider

Core component for managing Recoil state throughout your React application.

interface RecoilRootProps {
  initializeState?: (mutableSnapshot: MutableSnapshot) => void;
  override?: boolean;
  children: React.ReactNode;
}

const RecoilRoot: React.FC<RecoilRootProps>;

Root Provider

State Definition

Core functions for defining atoms and selectors that form the state graph.

interface AtomOptions<T> {
  key: string;
  default?: T | RecoilValue<T> | Promise<T> | Loadable<T> | WrappedValue<T>;
  effects?: ReadonlyArray<AtomEffect<T>>;
  dangerouslyAllowMutability?: boolean;
}

function atom<T>(options: AtomOptions<T>): RecoilState<T>;

interface ReadOnlySelectorOptions<T> {
  key: string;
  get: (opts: { get: GetRecoilValue; getCallback: GetCallback }) => 
    T | RecoilValue<T> | Promise<T> | Loadable<T> | WrappedValue<T>;
  cachePolicy_UNSTABLE?: CachePolicyWithoutEquality;
  dangerouslyAllowMutability?: boolean;
}

interface ReadWriteSelectorOptions<T> extends ReadOnlySelectorOptions<T> {
  set: (opts: {
    set: SetRecoilState;
    get: GetRecoilValue;
    reset: ResetRecoilState;
  }, newValue: T | DefaultValue) => void;
}

function selector<T>(options: ReadWriteSelectorOptions<T>): RecoilState<T>;
function selector<T>(options: ReadOnlySelectorOptions<T>): RecoilValueReadOnly<T>;

State Definition

Core Hooks

Essential React hooks for reading and writing Recoil state with automatic subscriptions.

function useRecoilValue<T>(recoilValue: RecoilValue<T>): T;
function useRecoilState<T>(recoilState: RecoilState<T>): [T, SetterOrUpdater<T>];
function useSetRecoilState<T>(recoilState: RecoilState<T>): SetterOrUpdater<T>;
function useResetRecoilState(recoilState: RecoilState<any>): () => void;
function useRecoilValueLoadable<T>(recoilValue: RecoilValue<T>): Loadable<T>;
function useRecoilStateLoadable<T>(recoilState: RecoilState<T>): [Loadable<T>, SetterOrUpdater<T>];

Core Hooks

Family Patterns

Functions for creating parameterized atoms and selectors that are memoized by parameter.

function atomFamily<T, P extends SerializableParam>(
  options: AtomFamilyOptions<T, P>
): (param: P) => RecoilState<T>;

function selectorFamily<T, P extends SerializableParam>(
  options: ReadWriteSelectorFamilyOptions<T, P>
): (param: P) => RecoilState<T>;

function selectorFamily<T, P extends SerializableParam>(
  options: ReadOnlySelectorFamilyOptions<T, P>
): (param: P) => RecoilValueReadOnly<T>;

Family Patterns

Concurrency Helpers

Utilities for coordinating multiple async operations and handling loading states.

function noWait<T>(state: RecoilValue<T>): RecoilValueReadOnly<Loadable<T>>;
function waitForAll<T extends Array<RecoilValue<any>>>(
  param: T
): RecoilValueReadOnly<UnwrapRecoilValues<T>>;
function waitForNone<T extends Array<RecoilValue<any>>>(
  param: T
): RecoilValueReadOnly<UnwrapRecoilValueLoadables<T>>;

Concurrency Helpers

Advanced Hooks

Powerful hooks for complex operations including callbacks, transactions, and state introspection.

function useRecoilCallback<Args extends ReadonlyArray<unknown>, Return>(
  fn: (interface: CallbackInterface) => (...args: Args) => Return,
  deps?: ReadonlyArray<unknown>
): (...args: Args) => Return;

function useRecoilSnapshot(): Snapshot;
function useGotoRecoilSnapshot(): (snapshot: Snapshot) => void;

Advanced Hooks

Loadable System

System for handling async state with loading, error, and success states.

type Loadable<T> = ValueLoadable<T> | LoadingLoadable<T> | ErrorLoadable<T>;

interface ValueLoadable<T> {
  state: 'hasValue';
  contents: T;
  getValue(): T;
  valueOrThrow(): T;
}

namespace RecoilLoadable {
  function of<T>(x: T | Promise<T> | Loadable<T>): Loadable<T>;
  function error(x: any): ErrorLoadable<any>;
  function loading(): LoadingLoadable<any>;
}

Loadable System

Memory Management

Tools for managing memory usage and preventing unwanted garbage collection of state.

function useRetain(
  toRetain: RecoilValue<any> | RetentionZone | Array<RecoilValue<any> | RetentionZone>
): void;

function retentionZone(): RetentionZone;

Memory Management

Core Types

// Base types
type NodeKey = string;
type SerializableParam = 
  | undefined | null | boolean | number | symbol | string
  | ReadonlyArray<SerializableParam>
  | ReadonlySet<SerializableParam>
  | Readonly<{[key: string]: SerializableParam}>;

// ID types
interface StoreID {
  readonly [StoreID_OPAQUE]: true;
}

interface SnapshotID {
  readonly [SnapshotID_OPAQUE]: true;
}

// Snapshot types
class Snapshot {
  getID(): SnapshotID;
  getLoadable<T>(recoilValue: RecoilValue<T>): Loadable<T>;
  getPromise<T>(recoilValue: RecoilValue<T>): Promise<T>;
  getNodes_UNSTABLE(opts?: { isModified?: boolean; isInitialized?: boolean }): Iterable<RecoilValue<unknown>>;
  getInfo_UNSTABLE<T>(recoilValue: RecoilValue<T>): RecoilStateInfo<T>;
  map(cb: (mutableSnapshot: MutableSnapshot) => void): Snapshot;
  asyncMap(cb: (mutableSnapshot: MutableSnapshot) => Promise<void>): Promise<Snapshot>;
  retain(): () => void;
  isRetained(): boolean;
}

class MutableSnapshot extends Snapshot {
  set: SetRecoilState;
  reset: ResetRecoilState;
}

// State info for debugging
interface RecoilStateInfo<T> {
  loadable?: Loadable<T>;
  isActive: boolean;
  isSet: boolean;
  isModified: boolean;
  type: 'atom' | 'selector';
  deps: Iterable<RecoilValue<T>>;
  subscribers: {
    nodes: Iterable<RecoilValue<T>>;
    components: Iterable<ComponentInfo>;
  };
}

interface ComponentInfo {
  name: string;
}

// State types
class RecoilState<T> {
  key: NodeKey;
  toJSON(): {key: string};
}

class RecoilValueReadOnly<T> {
  key: NodeKey;
  toJSON(): {key: string};
}

type RecoilValue<T> = RecoilValueReadOnly<T> | RecoilState<T>;

// Special values
class DefaultValue {
  private __tag: 'DefaultValue';
}

interface WrappedValue<T> {
  readonly [WrappedValue_OPAQUE]: true;
}

// Function types
type SetterOrUpdater<T> = (valOrUpdater: ((currVal: T) => T) | T) => void;
type GetRecoilValue = <T>(recoilVal: RecoilValue<T>) => T;
type SetRecoilState = <T>(
  recoilVal: RecoilState<T>,
  newVal: T | DefaultValue | ((prevValue: T) => T | DefaultValue)
) => void;
type ResetRecoilState = (recoilVal: RecoilState<any>) => void;
type GetCallback = <Args extends ReadonlyArray<unknown>, Return>(
  fn: (interface: SelectorCallbackInterface) => (...args: Args) => Return
) => (...args: Args) => Return;

// Selector callback interface
interface SelectorCallbackInterface extends CallbackInterface {
  node: RecoilState<unknown>;
}

// Utility function
function isRecoilValue(val: unknown): val is RecoilValue<any>;