An experimental state management lib based on React Hooks 🔱
MIT License
NOTE: not a real npm package yet!
npm install smook
TODO: write instructions...
First create a model:
// thing.model.ts
import { Model, Action, effect } from 'smook';
import { RootState, Models } from '../store';
import { Thing } from './thing.types';
export interface State {
things: Thing[];
isLoading: boolean;
hasError: boolean;
}
const thingModel = {
name: 'thing',
state: {
things: [],
isLoading: false,
hasError: false,
},
selectors: {
getNumOfThings: (state: RootState) => state.thing.things.length,
},
actions: {
fetchThings: effect<Models, RootState>(async function(models, getState) {
const state = getState();
console.log('> Current things:', state.thing.things);
// Fetch things from API etc.
const thing = {
id: '1', name:
'Foobar', size: 1
};
models.thing.actions.addThing(thing);
}),
addThing: (state: State, action: Action<Thing>): State => ({
...state,
things: [...state.things, action.payload],
}),
},
};
export type ThingModel = Model<typeof thingModel, State>;
export default thingModel;
// store.ts
import { createStore } from 'smook';
import { State as ThingState, ThingModel } from './thing/thing.model';
import thingModel from './thing/thing.model';
export interface Models {
thing: ThingModel;
}
export interface RootState {
thing: ThingState;
}
const store = createStore([thingModel]);
export default store;
// Thing.tsx
import React from 'react';
import { useModel } from 'smook';
import { Models } from '../store';
const Thing = () => {
const thingM = useModel<Models, 'thing'>('thing');
const things = thingM.select('things');
const hasError = thingM.select('hasError');
const isLoading = thingM.select('isLoading');
const numOfThings = thingM.select(thingM.selectors.getNumOfThings);
const { addThing, clearThings, fetchThings } = thingM.actions;
React.useEffect(() => {
fetchThings();
}, []);
// TODO: use values / actions in render...
return <div>Thing</div>;
};
export default Thing;