---
name: react/component-integration
description: >-
  ReactStore component integration guidance for React app/root wiring. Covers
  where to create/configure ReactStore, init/dispose ownership, app saga startup
  with reactStore.runSaga(sagaFn), direct selector signal reads in JSX/TSX,
  selector .useValue(...args) fallbacks for hook/plain-value boundaries, and
  Store-first dispatch without Svelte or StreamingStore lifecycle rules.
type: sub-skill
requires:
  - react
  - react/store
  - react/selector-lifecycle
sources:
  - "@augmentcode/ag-redux-toolkit/react-store"
  - ../selector-lifecycle/SKILL.md
  - ../store/SKILL.md
triggers:
  - React component integration
  - ReactStore component wiring
  - TSX Store dispatch
  - selector .useValue component
---
# React component integration — ReactStore app wiring

Use this skill when a React/TSX app has chosen the `ReactStore` family. Create
one configured `ReactStore`, initialize it before React renders selector-using
components, start app sagas after initialization, and dispatch through that same
configured store instance from components and handlers.

This is React Store family guidance. For the same app/package/code path, do not
apply Svelte readable/template/context lifecycle rules or `StreamingStore`/Kefir
observable patterns. If a mixed repository has a separate Svelte or Node/server
app, route that app to its own Store-family skill independently.

## 1. Create and configure the app `ReactStore`

Create the store in an app-owned module, not inside a component render or custom
hook. Pass app-owned reducers in the constructor map, optional middleware as the
second argument, and options such as `throttledSelectorFrequency` as the third
argument when needed.

```ts
// src/store/react-store.ts
import { ReactStore } from "@augmentcode/ag-redux-toolkit/react-store";
import type { StoreState } from "@augmentcode/ag-redux-toolkit/types";
import { todosReducer } from "./todos/todos-slice";

export const reactStore = new ReactStore({ todos: todosReducer });
export type AppState = StoreState<typeof reactStore>;
```

Key rules:

- Use `ReactStore` only from `@augmentcode/ag-redux-toolkit/react-store` for this React apppath.
- Use `reactStore.createSelector(...)` for app-local selectors so state inferencefollows the configured store.
- Do not add package-owned `@internal_` reducers or internal sagas.
- Do not create a new `ReactStore` per component, route, hook call, or render.

## 2. Initialize before React renders selector users

Call `reactStore.init(initialState?)` once at the app bootstrap/root ownership
boundary before rendering components that call direct signal selectors or
`.useValue(...args)` fallbacks. The returned disposer is equivalent to
`reactStore.dispose()`.

```tsx
// src/main.tsx
import React from "react";
import { createRoot } from "react-dom/client";
import { App } from "./App";
import { reactStore } from "./store/react-store";

const root = createRoot(document.getElementById("root")!);
const disposeStore = reactStore.init();

root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

if (import.meta.hot) {
  import.meta.hot.dispose(() => {
    root.unmount();
    disposeStore();
  });
}
```

Pass preloaded state to `reactStore.init(preloadedState)` when the app needshydration. Initialize before selector reads because `ReactStore.getSignalState()`throws before `init()` and after `dispose()`.

## 3. Dispose at the same owner boundary

The owner that calls `reactStore.init()` owns teardown. In browser apps this isusually the bootstrap file or test harness; in embedded/micro-frontend apps it maybe the host's mount/unmount adapter.

```tsx
export function mountReactApp(container: HTMLElement) {
  const root = createRoot(container);
  const disposeStore = reactStore.init();

  root.render(<App />);

  return () => {
    root.unmount();
    disposeStore();
  };
}
```

Do not hide `init()` in a child component `useEffect` if descendants render
selectors immediately; effects run after render, too late for direct signal
selectors or `.useValue(...args)` fallbacks that need the initialized store.

## 4. Start app sagas with `reactStore.runSaga(sagaFn)`

`reactStore.init()` starts package-owned runtime work but does not auto-start appsagas. Start each app saga explicitly after initialization and keep the returnedcancel function when the saga has a shorter lifetime than the whole store.

```ts
// src/main.tsx
import { reactStore } from "./store/react-store";
import { todosSaga } from "./store/todos/sagas/todos-saga";

const disposeStore = reactStore.init();
const cancelTodosSaga = reactStore.runSaga(todosSaga);

export function disposeAppRuntime() {
  cancelTodosSaga();
  disposeStore();
}
```

`reactStore.runSaga(sagaFn)` throws if `init()` has not been called or the saganame is reserved for package internals. Do not start `@internal_sagaManager`directly.

## 5. Read state in components with direct selector signals

React components and custom hooks should prefer direct selector calls and pass/read
the returned `ReadonlySignal<R>` where the Preact React signal integration
supports it. Use `.useValue(...args)` only for third-party components, existing
boundaries, or hook contracts that require a plain value and are impractical to
adapt.

```tsx
import { reactStore } from "../store/react-store";
import { selectTodoById } from "../store/todos/todos-selectors";
import { toggleTodo } from "../store/todos/todos-slice";

export function TodoRow({ id }: { id: string }) {
  const todo = selectTodoById(id);

  if (!todo.value) return null;

  return (
    <button onClick={() => reactStore.dispatch(toggleTodo(id))}>
      {todo.value.completed ? "✓" : "○"} {todo.value.title}
    </button>
  );
}
```

Component rules:

- Prefer direct selector calls for signal-aware components and custom hooks.
- Use `.useValue(...args)` only in React components or custom hooks that truly need a
  plain value.
- Import or otherwise receive the configured `ReactStore` instance and dispatchwith `reactStore.dispatch(action)` in event handlers.
- Use `.select(reactStore.state, ...args)` for one-shot reads inside handlers,callbacks, tests, or pure composition.
- Do not use `.useValue(...args)` as the default just to avoid adapting a consumer to
  accept a Preact React signal object.

## 6. Event-handler one-shot reads

Handlers should not call `.useValue(...args)` and should not create direct signals just
to read once. Use `.select(state, ...args)` with the initialized app store state
already in scope, then dispatch through the configured store.

```tsx
function DeleteTodoButton({ id }: { id: string }) {
  function onDelete() {
    const todo = selectTodoById.select(reactStore.state, id);
    if (todo && !todo.completed) {
      reactStore.dispatch(deleteTodo(id));
    }
  }

  return <button onClick={onDelete}>Delete</button>;
}
```

## 7. Common mistakes

### Initializing in an effect after children render

```tsx
// ❌ WRONG: children can call selectors before init has run.
function AppRoot() {
  React.useEffect(() => reactStore.init(), []);
  return <App />;
}
```

Initialize at the bootstrap/root owner before rendering selector users, or renderno selector-using children until after explicit initialization has completed.

### Creating stores in components or hooks

```tsx
// ❌ WRONG: a new runtime can be created every render/mount.
function TodoScreen() {
  const localStore = new ReactStore({ todos: todosReducer });
  const todos = localStore.createSelector((state) => state.todos.ids)();
  return <TodoList ids={todos.value} />;
}
```

Create/configure the store once in an app module or explicit mount adapter.

### Mixing Store families in one React app path

Do not use Svelte `$selector` syntax, Svelte readables, `+layout.svelte`, Svelte
context/`onDestroy`, `Store` from `@augmentcode/ag-redux-toolkit/svelte-store`,
`StreamingStore`, or Kefir observables in this React app path.

## 8. See also

- `react/store/SKILL.md` — `ReactStore` import, lifecycle, and `getSignalState()`.
- `react/selector-lifecycle/SKILL.md` — selector call modes across components,handlers, tests, composition, explicit binding, and sagas.
- `react/selectors/SKILL.md` — selector authoring for Preact React signals.
- `../setup/SKILL.md` — first-time Store-family selection and setup.