Skip to content

A minimum and lightweight external store for React and React Native application

License

Notifications You must be signed in to change notification settings

hoaxvo16/reactive-store

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

30 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Reactive store - a minimum and lightweight external store for React and React Native application

Table of contents

  1. Features

  2. Installation

  3. Usage

    3.1 Create new store

    3.2 Inject store to React component

    3.3 Update data from store

    3.4 Memo data from store

    3.5 Middleware

  4. Quick start

  5. React 18 support

  6. About

Features

  • Inject external data to React hook component
  • Support action to remove or update data
  • Light weight
  • TypeScript support

Installation

yarn add @mcsheffey/reactive-store

or

npm install @mcsheffey/reactive-store

Usage

Create a store

import { Store } from '@mcsheffey/reactive-store';

const store = new Store();

//init data

store.create('count', 0);

Inject store to React Component

  • Using StoreInjector to make your store binding data with React component
import { StoreInjector } from '@mcsheffey/reactive-store';

const Component = () => {
  return <div></div>;
};
export const App = StoreInjector(store, Component);
//or
export const App = StoreInjector(store, () => {
  return <div></div>;
});
  • Many store can be inject into one Component, and two or more Component can use the same store
export const App = StoreInjector([countStore, todoStore], () => {
  return <div></div>;
});

Update or remove data from store

  • To update or remove data from store use can use store action. There are two kind of action update (update data) or remove (delete data) from store. Note: add new data to store will not trigger component rerender. This is good because data need to be declare at first time.
//this will not rerender component

store.create('blah', 'hmmm???');

//this two above will trigger component to rerender
store.update('count', count + 1);
store.remove('count');

Memo data

For some reason you may don't want to recreate data that extract from store every rerender, this can be achieved by using useCallback hook:

import * as React from 'react';
import { StoreInjector, Store } from '@mcsheffey/reactive-store';

const store = new Store();
store.create('count', 0);

const Component = () => {
  //Memo count 'state'
  const countMemo = React.useCallback(() => {
    return store.get('count');
  }, []);
  //Effect on memo
  React.useEffect(()=>{
     console.log("count change")
  },[countMemo()])
  return <p>{countMemo()}</p>;
};

export const App = StoreInjector(store, Component);

Middleware

  • Middleware is a method provide by Store class, it allow you to control, debugging store behavior

  • Using middleware:

import {
  DispatchAction,
  Store,
  StoreInjector,
} from '@mcsheffey/reactive-store';

export const store = new Store();

store.applyMiddleware(
  (key: string, current: any, payload: any, type: DispatchAction) => {
    console.log(key, current, payload, type);
  }
);

store.create('count', 0);
for (let i = 0; i < 2; i++) {
  const count = store.get('count');
  store.update('count', count++);
}
store.delete('count');
/*
Log:
"count" 0 undefined "create"
"count" 0 1 "update"
"count" 1 2 "update"
"count" 2 undefined "delete"
*/
  • key: the "key" of current data
  • current: current value of data with "key"
  • payload: a new value that use to update data with given key
  • type: an action type (create,update or delete)
  • You cant abort an action by return false in middleware function
store.applyMiddleware(
  (key: string, current: any, payload: any, type: DispatchAction) => {
    //abort action if count > 5
    if (count > 5) {
      return false;
    }
  }
);

store.create('count', 0);
for (let i = 0; i < 10; i++) {
  const count = store.get('count');
  store.update('count', count++);
}

Quick start

import {
  Store,
  StoreInjector,
  DispatchAction,
} from '@mcsheffey/reactive-store';

const store = new Store();

store.applyMiddleware(
  (key: string, current: any, payload: any, type: DispatchAction) => {
    console.log(key, current, payload, type);
    if (count > 5) {
      return false;
    }
  }
);

const keys = {
  count: 'count',
};
/*Add data to store*/
store.create(keys.count, 0);

const Component = () => {
  /*Get data from store */
  const count: number = store.get(keys.count);
  return (
    <div className="App">
      <button onClick={() => store.update(keys.count, count + 1)}>+</button>
    </div>
  );
};

const App = StoreInjector(store, Component);

const rootElement = document.getElementById('root');
ReactDOM.render(<App />, rootElement);

React 18 support

  • See document for React version 18 here

About

About

A minimum and lightweight external store for React and React Native application

Resources

License

Stars

Watchers

Forks

Packages

No packages published