flooks

Auto optimized React Hooks state manager. Tiny, simple, smooth.

Features

  • Gorgeous auto optimized re-render
  • Intelligent loading state
  • Interconnected modules
  • Extremely simple API

Install

yarn add flooks

# npm install flooks

Usage

import useModel from 'flooks';

const counter = ({ get, set }) => ({
  count: 0,
  add() {
    const { count } = get();
    set({ count: count + 1 });
  },
  async addAsync() {
    await new Promise((resolve) => setTimeout(resolve, 1000));
    const { add } = get();
    add();
  },
});

const useCounter = () => useModel(counter);

function Counter() {
  const { count, add, addAsync } = useCounter();

  return (
    <div>
      <p>{count}</p>
      <button onClick={add}>+</button>
      <button onClick={addAsync}>+~ {addAsync.loading && '...'}</button>
    </div>
  );
}

* Intelligent loading state - if someFn is async, someFn.loading is its loading state. If someFn.loading is not used, no extra re-render.

Demo

Edit flooks

Gorgeous re-render optimization

Through proxy, flooks realizes a gorgeous auto optimization, re-render completely on demand, when React is truly "react".

Only actually used data will be injected into the component. If not, just not injected.

Only functions never trigger re-render

const { fn } = useDemoModel(); // A component

const { b, setB } = useDemoModel(); // B component
setB(); // A no re-render

If only functions used in A, others update won't trigger A re-render.

Unused state never trigger re-render

const { a } = useDemoModel(); // A component

const { b, setB } = useDemoModel(); // B component
setB(); // A no re-render

If some state not used in A, others update won't trigger A re-render.

Unused loading never trigger re-render

const { someFn } = useDemoModel(); // A component
someFn(); // no someFn.loading, no extra re-render

If someFn.loading not used in A, someFn() won't trigger extra re-render.

If someFn is async, with normal loading solutions, even someFn.loading is not used, re-render will trigger at least twice (turn true then false). However, with flooks, no invisible loading updates, if someFn.loading is not used.

API

useModel()

import useModel from 'flooks';

const useSomeModel = () => useModel(someModel);

get() & set()

import useModel from 'flooks';
import { anotherModel } from './useAnotherModel';

const someModel = ({ get, set }) => ({
  someFn() {
    const { a, b } = get(); // get own model
    const { x, y } = get(anotherModel); // get other models

    set({ a: a + b }); // payload style
    set((state) => ({ a: state.a + state.b })); // function style
  },
});

export default () => useModel(someModel);

* Interconnected modules - call get(anotherModel) in someModel to get other models, all models can be connected.

License

MIT License