A minimal and flexible abstraction for creating typed React Context state containers with built-in dispatch handling.
- Tiny, dependency-free abstraction
- Type-safe state and actions
- Works with both functional components and consumers
- Compatible with async actions (if handled externally)
npm install react-context-lite
## How to use it
```typescript
interface TeamsAppState extends AppState {
teams: TeamsRoot
}
const initialValue: TeamsAppState = {
timestamp: Date.now(),
teams: {
id: 'root',
type: 'root',
name: 'Root',
depth: 0,
children: [],
},
}
const {
Consumer: TeamsStateConsumer,
Provider: TeamsStateProvider,
useAppState: useTeamsAppContext,
} = createAppState<TeamsAppState>(initialValue);
const {state, dispatch} = useTeamsAppContext();
console.log('Teams State', state && state.teams.name);
// Synchronous Action
const actionAddTeam = (name: string, teamId: number) =>
(state: TeamsAppState) => {
// Modify state
return state
}
dispatch(actionAddTeam('New Team', 0));
function apiCreateTeam(name: string): Promise<Team> {
return new Promise<Team>((resolve, reject) => {
resolve({
id: '111',
name,
depth: 1,
type: 'teams',
allocation: 100,
description: name,
strategic_value: 1000000,
})
})
}
// Asynchronous Action
const actionAddTeamAsync = (name: string, teamId: number) => {
apiCreateTeam(name)
.then((team) => {
dispatch(actionAddTeam(team.name, 0));
});
};
actionAddTeamAsync('New Team', 0);
function SomeConsumer() {
return (
<TeamsStateConsumer>
{({dispatch}) => (
<button
onClick={() => dispatch(actionAddTeam('Some Team', 0))}>
Dispatch Some
</button>
)}
</TeamsStateConsumer>
);
}
function SomeProvider() {
return (
<TeamsStateProvider>
<SomeConsumer/>
</TeamsStateProvider>
);
}