react-svs-di
v1.0.0
Published
react-svs-di is a react state managent library with these features:
Downloads
8
Readme
react-svs-di
react-svs-di is a react state managent library with these features:
- Typescript first. Get full intellisense and type-checking when:
- Subscribe shared state
- Update shared state
- Manage async works
Using typescript with 'redux-like' state managent library is a cumbersome development experience. Too many boilerplate code(define actions, import actions creator, dispatch action, define reducer, connect, manage effects). And it is hard to get full intellisense and type-checking(string-based action type).
- Dependency injection. We encourage users to 'depend on abstractions, don't depend on implementations'. (dependency inversion principle)
- We use react context to implement DI, but we resolve the problem of 'provider hell', which is ignored by most 'state management libraries'.
- Embrace react hooks. Hooks is a booming trend in react community. You can benefit from the community while using react-svs-di. For example, you can use swr, which is a fantastic react hook library!
- Rxjs friendly. rxjs fit very well in react-svs-di. react-svs-di makes it very easy to use rxjs in react.
If you don't like/know rxjs, feel free to drop it!
Basic example
import React from 'react';
import {
injectable,
withDIContainer,
useDIConsumer,
SharedState,
} from 'react-svs-di';
@injectable()
class CountSvs {
private sum = new SharedState(0);
// this is a react hook to be run in consumer
useCountNumber() {
const value = this.sum.useValue();
return value;
}
public increase() {
this.sum.setValueWithFn(prev => prev + 1);
}
public decrease() {
this.sum.setValueWithFn(prev => prev - 1);
}
public reset() {
this.sum.setValue(0);
}
}
export const Demo: React.FC = withDIContainer([CountSvs])(() => {
const [dataSvs] = useDIConsumer([CountSvs]);
// auto re-render when the SharedState changed
const sum = dataSvs.useCountNumber();
return (
<div>
<h1>Basic Demo - SharedState version</h1>
<p>sum: {sum}</p>
<button
onClick={() => {
dataSvs.increase();
}}
>
increase
</button>
<button
onClick={() => {
dataSvs.decrease();
}}
>
decrease
</button>
<button
onClick={() => {
dataSvs.reset();
}}
>
reset
</button>
</div>
);
});
Workflow
- Split your app logic and state into multiple services.
- shared state.
- side effects. Can be async.
- procedures to update state.
- communicate with backend.
- Provide those services at appropriate places of component tree.
- Component ask for some service.
- Component can 'use' service's state to render view.
- Component can call react hooks provided by the service.
- Component call side effect in it's event handler.
The service should be provided above the component.
- If some side effects change some shared states. Components (that 'use' the shared states) will re-render automatically.
- A service can ask for other services(dependency injection). And call other services' procedures.
More examples
- Some examples use 'console.log' to proof a point. See it int the 'Actions' tab(or browser dev tool).
- The source code of an example is in the 'Story' tab.
- Explanation of an example is in the comment of the 'Story' tab.