pelotom / use-methods

A simpler way to useReducers
MIT License
705 stars 22 forks source link

Alternative class based API #21

Closed dalevink closed 3 years ago

dalevink commented 5 years ago

Inspired by the typing goodness of useMethods, I've been using a modified version that works nicely with Typescript. I've been calling it useInstance :)

const state = useInstance(() => new CounterState());

And you define your state/actions in a single class:

class CounterState {

  nextId = 0;
  counters = [];
  updateCount = 0;

  addCounter() {
    this.counters.push({ id: this.nextId++, count: 0 });
  }
  incrementCounter(id) {
    this.getCounter(id).count++;
  }
  resetCounter(id) {
    this.getCounter(id).count = 0;
  }

  // "Dispatch" methods can call other private methods (and return values)

  private getCounter(id) {
    return this.counters.find(counter => counter.id === id);
  }

  // You can return the state to replace the state completely
  // Otherwise, do not return state (see immer for details)

  startOver() {
    return new CounterState();
  }

  // I've been playing with this idea.. 
  // A "magic" method that runs just before every dispatch end. 

  beforeDispatchEnd() {
    this.updateCount++;
    console.log("Update done. Count: " + this.updateCount);
  }
}

What I like about this API:

Here's a demo (as a JS class, but intended for Typescript): https://codesandbox.io/embed/usereducer-vs-usemethods-comparison-llmvr

As it's a little out of scope I was going to create a new project.. or ... would you be interested in integrating something like this?

Related #18 #2

pelotom commented 5 years ago

Looks interesting; I wonder what the advantages/disadvantages of this approach are vs MobX. But yeah, I think it is out of scope for this library.