Skip to content

Latest commit

 

History

History
226 lines (166 loc) · 4.79 KB

File metadata and controls

226 lines (166 loc) · 4.79 KB

kisstate

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.


Features ✨

  • Minimal API: Quickly declare observables, computed properties, and watchers via decorators
  • Deep React Integration: Automatic component reactivity through observer HOC
  • Zero Configuration: Works out-of-the-box with no complex setup

Installation 📦

npm install kisstate
# or
yarn add kisstate

Core Concepts 🧠

1. Observable Class

Declare observable classes using @ObservableClass decorator:

import { ObservableClass } from 'kisstate';

@ObservableClass
class User {
  name = 'jude';
  age = 26;

  constructor() {
    this.age = 17;
  }
}

2. Property Observation

Watch specific property changes with @watchProps:

@watchProps('age')
onAgeChange() {
  console.log('age changed:', this.age);
}

@watchProps('name')
onNameChange() {
  console.log('name changed:', this.name);
}

3. Computed Properties

Declare auto-updating computed properties with @computed:

@computed('age')
get nextAge() {
  return this.age + 1;
}

@computed('nextAge')
get nextnextAge() {
  return this.nextAge + 1;
}

4. React Component Binding

Connect React components using observer HOC:

const HocApp = observer(App);

5. Important Notes 📢

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 };
  }
}

Complete Example 🚀

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);

How It Works 🔧

  1. Reactive System: Implements property access tracking through Proxy
  2. Batch Updates: Automatically triggers related component updates after state changes

Best Practices ✅

  1. Single Source of Truth: Create independent Observable Classes for each domain model
  2. Fine-grained Observation: Split watchers according to business needs
  3. Computed Property Caching: Automatic result caching to avoid recomputation
  4. Component Layering: Use observer only on leaf components for optimization

API Documentation 📖

API Description
@ObservableClass Declares an observable class
@watchProps Watches specified properties
@computed Declares computed properties
observer Creates reactive React component

License

MIT © [ailuoku6]


Make state management simple again! 🎉
With kisstate, focus on business logic instead of state management complexities. Contributions and suggestions are welcome!