# state-context

Composable React context utilities for layered state management. Supports multiple simultaneous contexts, partial/functional updates, and nested providers that inherit outer state.

```typescript
import {
    createStateContext,
    StateContextProvider,
} from '@yaoc1996/js-tools/react-utils'
```

---

## `createStateContext<T>()`

Creates a typed React context for state of shape `T`. The default value has an empty object as state and a `setState` that throws if called outside a provider.

### Returns

`Context<StateContextType<T>>` — a React context with tuple `[state, setState]` as its value.

### Example

```typescript
import { createStateContext } from '@yaoc1996/js-tools/react-utils'

interface ThemeState { color: string; size: number }
const ThemeContext = createStateContext<ThemeState>()
```

### Notes

- Calling `setState` on the default context value (outside a provider) throws `"Invalid setContext method."`.
- Each call returns a new, independent context object.

---

## `StateContextProvider({ contexts, values, children })`

A React component that wraps children with one or more `InternalStateContextProvider` layers. Each layer reads the outer provider's state as `prevState`, applies the given `value` on top, and exposes a `setState` that merges updates (partial or functional) into an internal override slice.

### Props

| Name | Type | Description |
|------|------|-------------|
| `contexts` | `Context<StateContextType<any>>[]` | The contexts to provide. |
| `values` | Typed tuple matching `contexts` | Initial values for each context. Each element must match the state shape of the corresponding context. |
| `children` | `ReactNode` | Children to render inside the provider(s). |

### State resolution order

Each layer resolves state as: `{ ...prevState, ...value, ...internalState }` where `prevState` is from the nearest outer provider of the same context, `value` is the prop passed to this layer, and `internalState` is accumulated via `setState` calls.

### Example

```typescript
import { createStateContext, StateContextProvider } from '@yaoc1996/js-tools/react-utils'

const SelectionCtx = createStateContext<{ selected: string | null }>()

function App() {
    return (
        <StateContextProvider
            contexts={[SelectionCtx]}
            values={[{ selected: null }]}
        >
            <MyComponent />
        </StateContextProvider>
    )
}
```

### Notes

- `contexts` and `values` arrays are stabilised with `useMemoObjectShallow` — passing a new array literal with the same contents does not trigger re-renders.
- Providers are applied in order: `contexts[0]` is the outermost layer, `contexts[n-1]` is the innermost.
- Nested `StateContextProvider` for the same context automatically inherits outer state via `useContext`.

---

## Types

```typescript
type GetState<T extends object> = (prevState: T) => Partial<T>
type NextState<T extends object> = Partial<T> | GetState<T>
type SetState<T extends object> = (param: NextState<T>) => void
type StateContextType<T extends object> = [state: T, setState: SetState<T>]
```
