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
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.