immer-context provides small, typed state stores scoped to a React component
subtree. It combines React Context with Immer
so descendants can update nested state using immutable recipes.
It is intended for state local to a feature, such as a form, wizard, or editor. It is not a replacement for application-wide state libraries.
npm install immer-context react immerReact and Immer are peer dependencies and must also be installed by your app.
Create a context from an initial value. Each mounted Provider owns an independent state instance.
import React from 'react';
import { createImmerContext } from 'immer-context';
const FormState = createImmerContext({
name: '',
address: { city: '' },
});
function CityField() {
const [form, updateForm] = FormState.useImmerContext();
return (
<input
value={form.address.city}
onChange={event =>
updateForm(draft => {
draft.address.city = event.target.value;
})
}
/>
);
}
function Form() {
return (
<FormState.Provider>
<CityField />
</FormState.Provider>
);
}The state type is inferred from the initial value. Updates accept an Immer recipe, so you can mutate the draft; Immer produces the next immutable state. The hook throws a descriptive error if used outside its matching Provider.
Each Provider starts from the factory's initial value. Two Providers created from the same context are isolated from one another. Components using the hook rerender when the context state changes, following React Context behavior.
Returns an object with:
Provider: owns state for its subtree.useImmerContext(): returns[state, updateState]; only call it inside a matching Provider.
Pass an Immer recipe that mutates its draft.
updateState(draft => {
draft.name = 'Ada';
});The old withIContext and name-based useIContext API has been removed. It
used a module-level context registry and could connect a hook to a different
Provider implementation. The factory API makes the Provider/hook relationship
explicit and supports independent Provider instances.