kisstate is a lightweight state management library following the KISS (Keep It Simple, Stupid) principle, designed specifically for React applications. Through concise decorators and reactive design, it helps developers easily manage component states without complex state logic.
- Minimal API: Quickly declare observables, computed properties, and watchers via decorators
- Deep React Integration: Automatic component reactivity through
observerHOC - Zero Configuration: Works out-of-the-box with no complex setup
npm install kisstate
# or
yarn add kisstateDeclare observable classes using @ObservableClass decorator:
import { ObservableClass } from 'kisstate';
@ObservableClass
class User {
name = 'jude';
age = 26;
constructor() {
this.age = 17;
}
}Watch specific property changes with @watchProps:
@watchProps('age')
onAgeChange() {
console.log('age changed:', this.age);
}
@watchProps('name')
onNameChange() {
console.log('name changed:', this.name);
}Declare auto-updating computed properties with @computed:
@computed('age')
get nextAge() {
return this.age + 1;
}
@computed('nextAge')
get nextnextAge() {
return this.nextAge + 1;
}Connect React components using observer HOC:
const HocApp = observer(App);kisstate does not recursively deeply observe nested Objects and Arrays. To trigger changes and side effects, use destructuring assignments.
@ObservableClass
class User {
name = 'jude';
age = 18;
skill: string[] = [];
wallet: any = {};
constructor() {}
setSkill(skill: string[]) {
this.skill = skill;
}
addSkill(skill: string) {
this.skill.push(skill);
// Note: Destructuring assignment is required here to trigger dependency updates
this.skill = [...this.skill];
}
setWalletContent(key: string, value: any) {
this.wallet[key] = value;
// Note: Destructuring assignment is required here to trigger dependency updates
this.wallet = { ...this.wallet };
}
}import { ObservableClass, watchProps, observer, computed } from 'kisstate';
// 1. Declare observable class
@ObservableClass
class User {
name = 'jude';
age = 26;
skill: string[] = [];
wallet: any = {};
constructor() {
this.age = 17;
}
setSkill(skill: string[]) {
this.skill = skill;
}
addSkill(skill: string) {
this.skill.push(skill);
// Note: Destructuring assignment is required here to trigger dependency updates
this.skill = [...this.skill];
}
setWalletContent(key: string, value: any) {
this.wallet[key] = value;
// Note: Destructuring assignment is required here to trigger dependency updates
this.wallet = { ...this.wallet };
}
// 2. Property change observation
@watchProps('age')
onAgeChange() {
console.log('Age changed:', this.age);
}
// 3. Computed properties
@computed('age')
get nextAge() {
return this.age + 1;
}
@computed('nextAge')
get nextnextAge() {
return this.nextAge + 1;
}
}
// 4. Create state instance
const user = new User();
// 5. React component
function App() {
return (
<div className="card">
<button onClick={() => user.age++}>
Current age: {user.age}
</button>
<p>Next year: {user.nextAge}</p>
<p>After next year: {user.nextnextAge}</p>
</div>
);
}
// 6. Bind state observation
export default observer(App);- Reactive System: Implements property access tracking through Proxy
- Batch Updates: Automatically triggers related component updates after state changes
- Single Source of Truth: Create independent Observable Classes for each domain model
- Fine-grained Observation: Split watchers according to business needs
- Computed Property Caching: Automatic result caching to avoid recomputation
- Component Layering: Use
observeronly on leaf components for optimization
| API | Description |
|---|---|
@ObservableClass |
Declares an observable class |
@watchProps |
Watches specified properties |
@computed |
Declares computed properties |
observer |
Creates reactive React component |
MIT © [ailuoku6]
Make state management simple again! 🎉
With kisstate, focus on business logic instead of state management complexities. Contributions and suggestions are welcome!