Simple state management for react.
npm install nostate --save
yarn add nostate
This lib is motived by Vue 3 Composition API and redux. There are many disadvantages using the pure Vue 3 Composition API in react. So I introduce the predictability from redux and immutable feature in Composition API. Currently the immutable feature is not fully realized, it is more proper to say the state is unchangeable now, and the fully immutable feature will be like immer and be finished in the version.
- state is immutable
- state is predictable like redux
- No boilerplate code
- Fully typescirpt
- Easy learn, easy write, easy test
Component scope state.
Every component has independent state when they use the same setup
import { reactive, reducer } from 'nostate';
const sleep = () => {
return new Promise((resolve) => {
setTimeout(resolve, 2000);
});
};
export const setup = () => {
const state = reactive({ count: 0 });
// state can only change in reducer
const increase = reducer((num: number) => {
state.count += num;
});
// async function and commit data use reducer
const asyncIncrease = async (num: number) => {
await sleep();
increase(num);
};
return {
state,
increase,
asyncIncrease,
};
};
export function App() {
// state is immutable here
const setupBinds = useCreateSetup(setup);
const { state, increase, asyncIncrease } = useSetupBinds(setupBinds);
return (
<div>
<h1>Global Bpp: {state.count}</h1>
<button onClick={() => increase(1)}>+</button>
<button onClick={() => asyncIncrease(2)}>async+</button>
</div>
);
}
Global scope state
Every component has same state when they use the global setup
import { reactive, reducer, createSetup } from 'nostate';
// create will run wrap function immediately
export const setup = createSetup(() => {
const state = reactive({ count: 0 });
const increase = reducer((num: number) => {
state.count += num;
});
return {
state,
increase,
};
});
export function App() {
const { state, increase } = useSetupBinds(setup);
return (
<div>
<h1>Global Bpp: {state.count}</h1>
<button onClick={() => increase(1)}>+</button>
</div>
);
}
const original: any = { foo: 1 };
const observed = reactive(original);
observed.foo++;
console.log(original.foo); // 2
const value = reactive<{ foo?: number }>({});
const cValue = computed(() => value.foo);
expect(cValue.value).toBe(undefined);
value.foo = 1;
expect(cValue.value).toBe(1);
state can only change in function wrapped by reducer
const increase = reducer((num: number) => {
state.count += num;
});