Skip to content

๐Ÿธ A state manager for React Hooks

License

Notifications You must be signed in to change notification settings

alucardhyx/flooks

ย 
ย 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

60 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐Ÿธ flooks

A state manager for React Hooks. Maybe the simplest. ^_^

npm Travis (.org) Codecov npm bundle size npm type definitions GitHub

๐Ÿฐ Simple | ๐Ÿญ Auto loading | ๐Ÿ• Modules | ๐Ÿฅ‚ Flexible


English | ็ฎ€ไฝ“ไธญๆ–‡


Install

yarn add flooks

or

npm install flooks

Usage

import { setModel, useModel } from 'flooks';

const counter = {
  state: {
    count: 0,
  },
  actions: ({ model, setState }) => ({
    increment() {
      const { count } = model();
      setState({ count: count + 1 });
    },
    decrement() {
      const { count } = model();
      setState({ count: count - 1 });
    },
    async incrementAsync() {
      const { increment } = model();
      await new Promise((resolve) => setTimeout(resolve, 1000));
      increment();
    },
  }),
};

setModel('counter', counter);

function Counter() {
  const { count, increment, decrement, incrementAsync } = useModel('counter');
  return (
    <>
      Count: {count}
      <button onClick={increment}>+</button>
      <button onClick={decrement}>-</button>
      <button onClick={incrementAsync}>+ async{incrementAsync.loading && '...'}</button>
    </>
  );
}

Demo

Edit flooks

API

setModel()

setModel(name, model);

Accepts a name string and an model object, initialize the model.

The model object needs to contain a state object and an actions function.

useModel()

const { someState, someAction } = useModel(name);

A React Hook. Accepts a name, returns the initialized model with its state and actions.

({ model, setState }) => realActions

actions: ({ model, setState }) => ({ someAction() {} });

The argument of actions contains two functions, model() and setState(), can be used in every action.

model()

const { someState, someAction } = model(name?);

Returns the same as useModel(), but when get own model, name can be omitted.

i.e. model() for own model, model('other') for other models.

setState()

setState(payload);

Update own model's state with the payload object, can't update other models'.

FAQ

Auto loading?

actions: ({ model, setState }) => ({
  async someAsyncAction() {},
});

When an action is async, someAsyncAction.loading can be use.

Code splitting?

Supported naturally. Call setModel() in components, then use libraries like loadable-components.

Set models together?

import { setModel } from 'flooks';
import a from '...';
...

const models = { a, b, c };
Object.entries(models).forEach(([name, model]) => {
  setModel(name, model);
});

This is not recommended. Call setModel() separately in components, which is more clear and flexible.

Philosophy

1. Our philosophy is decentralization, so we recommend to bind a model and a route entry component as one module, call setModel() in the component to bind two.

2. No need to add a file like store.js or models.js, because no need to distribute the store from top now. Without the centralized store, just the modules consisting of components and models in the lower level.

3. A model has its own space, with useModel() and model(), all other models can be reached. Models are independent, but also connected.

4. Don't initialize a model multiple times using setModel(), if have a "common" model used in several places, recommend to to initialize it in an upper component, such as App.jsx.

5. That's all, enjoy it~

License

MIT License (c) nanxiaobei

About

๐Ÿธ A state manager for React Hooks

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • JavaScript 53.2%
  • TypeScript 46.8%