hub-flow
TypeScript icon, indicating that this package has built-in type declarations

1.2.1 • Public • Published

Hub Flow

Hub Flow is a pattern for managing state in React.js applications. It steals the great principles from Flux & Redux (one-way data flow), but leaves out the ceremonious complexity. Hub Flow comes with built in immutability, which means a huge performance boost and an end to accidental state mutation bugs. Hub Flow is powered by Freezer.js

npm install --save hub-flow

Getting Started

hub.ts

import createHub, { Hub } from "hub-flow";
import { DBUser, Counter } from "models";
 
// Describe the Shape of your App State
export interface AppState {
  counter: { count: number };
  // Store the server responses on App state
  // And transform the data via the Model (see below)
  // Basically, store serializable stuff on app state so
  // caching works properly
  users: DBUser[];
}
 
// Setup the default AppState
// Unless you specify, the app state will be loaded
// from cache if possible
const DEFAULT_STATE: AppState = {
  users: [],
  counter: new Counter(),
};
 
// Create the HUB
let hub = createHub(DEFAULT_STATE);
 
export default hub;

Once you setup a hub, you want to create a Model for the various slices/layers of your application state. In the Model you can

  • create methods that update AppState
  • Setup specific listeners so that your component only re-renders when it needs to.
  • Transform data / setup computed values
  • Setup relationships with other layers of the application (optionally)

counter.models.ts

import hub from "global/hub";
import { Model } from "hub-flow";
 
export class Counter extends Model<Counter> {
  getDependencies() {
    return [hub.state.counter];
  }
 
  get count() {
    return hub.state.counter.count;
  }
  increment() {
    hub.state.counter.set({ count: hub.state.counter.count + 1 });
  }
  decrement() {
    hub.state.counter.set({ count: hub.state.counter.count - 1 });
  }
  reset() {
    hub.state.counter.set({ count: 0 });
  }
}

Then use it in a React component by leveraging useModel.

import React from "react";
import { Counter } from "models";
import { useModel } from "hub-flow";
 
export function CounterDisplay() {
  console.log("CounterDisplay -> CounterDisplay");
  const counter = useModel(Counter);
  return <div>Counter: {counter.count}</div>;
}
 
export function CounterButtons() {
  console.log("CounterButtons -> CounterButtons");
  const counter = useModel(Counter);
  return (
    <div>
      <button onClick={counter.reset}>Reset</button>
      <button onClick={counter.decrement}>-1</button>
      <button onClick={counter.increment}>+1</button>
    </div>
  );
}

Under the covers, useModel hook:

  • Wraps your Model's contstructor witha React.useMemo so that you don't get a new instance of your model with each render
  • Additional params will be passed to your Model's constructor
  • Wires up to the listeners that you defined in your Model so that React renders any time that listener receives and update event.
useModel(Counter) => new Counter();
// Additional params will be passed to your Model's constructor
useModel(User, 3) => new User(3);

Readme

Keywords

none

Package Sidebar

Install

npm i hub-flow

Weekly Downloads

27

Version

1.2.1

License

ISC

Unpacked Size

18.4 kB

Total Files

20

Last publish

Collaborators

  • droopytersen