Socket
Socket
Sign inDemoInstall

react-hookstore

Package Overview
Dependencies
Maintainers
1
Versions
28
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-hookstore - npm Package Compare versions

Comparing version 1.0.8 to 1.1.0

63

dist/react-hookstore.js

@@ -110,2 +110,3 @@ (function webpackUniversalModuleDefinition(root, factory) {

/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "createStore", function() { return createStore; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getStoreByName", function() { return getStoreByName; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "useStore", function() { return useStore; });

@@ -124,3 +125,5 @@ /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0);

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var stores = {};

@@ -131,8 +134,23 @@

};
var StoreInterface = function StoreInterface(name, store, useReducer) {
_classCallCheck(this, StoreInterface);
this.name = name;
useReducer ? this.dispatch = store.setState : this.setState = store.setState;
this.getState = function () {
return store.state;
};
};
function getStoreByIdentifier(identifier) {
var name = identifier instanceof StoreInterface ? identifier.name : identifier;
return stores[name];
}
/**
* Creates a new store
* @param {Object} config - An object containing the store setup
* @param {*} config.state [{}] - The store initial state. It can be of any type.
* @param {String} config.name ['store'] - The store namespace. not required if you're not using multiple stores within the same app.
* @callback confg.reducer [null]
* @param {String} name - The store namespace. not required if you're not using multiple stores within the same app.
* @param {*} state [{}] - The store initial state. It can be of any type.
* @callback reducer [null]
*/

@@ -142,14 +160,14 @@

*
* @param {config.reducer} prevState, action - The reducer handler. Optional.
* @param {reducer} prevState, action - The reducer handler. Optional.
*/
function createStore(_ref) {
var _ref$state = _ref.state,
state = _ref$state === void 0 ? {} : _ref$state,
_ref$name = _ref.name,
name = _ref$name === void 0 ? 'store' : _ref$name,
_ref$reducer = _ref.reducer,
reducer = _ref$reducer === void 0 ? defaultReducer : _ref$reducer;
function createStore(name) {
var state = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var reducer = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : defaultReducer;
if (typeof name !== 'string') {
throw 'store name must be a string';
}
if (stores[name]) {

@@ -173,13 +191,26 @@ throw 'store already exists';

store.setState = store.setState.bind(store);
store.public = new StoreInterface(name, store, reducer !== defaultReducer);
stores = Object.assign({}, stores, _defineProperty({}, name, store));
return store;
return store.public;
}
/**
* Returns a store instance based on its name
* @param {String} name - The name of the wanted store
*/
function getStoreByName(name) {
try {
return stores[name].public;
} catch (e) {
throw 'store does not exist';
}
}
/**
* Returns a [ state, setState ] pair for the selected store. Can only be called within React Components
* @param {String} name ['store'] - The namespace for the wanted store
* @param {String|StoreInterface} identifier ['store'] - The identifier for the wanted store
*/
function useStore() {
var name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'store';
var store = stores[name];
var identifier = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'store';
var store = getStoreByIdentifier(identifier);

@@ -186,0 +217,0 @@ if (!store) {

@@ -1,1 +0,1 @@

!function(t){var e={};function r(n){if(e[n])return e[n].exports;var o=e[n]={i:n,l:!1,exports:{}};return t[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}r.m=t,r.c=e,r.d=function(t,e,n){r.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},r.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},r.t=function(t,e){if(1&e&&(t=r(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)r.d(n,o,function(e){return t[e]}.bind(null,o));return n},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="",r(r.s=1)}([function(t,e){t.exports=void 0},function(t,e,r){"use strict";r.r(e),r.d(e,"createStore",function(){return u}),r.d(e,"useStore",function(){return i});var n=r(0);let o={};const s=(t,e)=>e;function u({state:t={},name:e="store",reducer:r=s}){if(o[e])throw"store already exists";const n={state:t,reducer:r,setState(t){this.state=this.reducer(this.state,t),this.setters.forEach(t=>t(this.state))},setters:[]};return n.setState=n.setState.bind(n),o=Object.assign({},o,{[e]:n}),n}function i(t="store"){const e=o[t];if(!e)throw"store does not exist";const[r,s]=Object(n.useState)(e.state);return Object(n.useEffect)(()=>()=>{e.setters=e.setters.filter(t=>t!==s)},[]),e.setters.includes(s)||e.setters.push(s),[r,e.setState]}}]);
!function(t){var e={};function r(n){if(e[n])return e[n].exports;var s=e[n]={i:n,l:!1,exports:{}};return t[n].call(s.exports,s,s.exports,r),s.l=!0,s.exports}r.m=t,r.c=e,r.d=function(t,e,n){r.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},r.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},r.t=function(t,e){if(1&e&&(t=r(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var s in t)r.d(n,s,function(e){return t[e]}.bind(null,s));return n},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="",r(r.s=1)}([function(t,e){t.exports=void 0},function(t,e,r){"use strict";r.r(e),r.d(e,"createStore",function(){return i}),r.d(e,"getStoreByName",function(){return c}),r.d(e,"useStore",function(){return a});var n=r(0);let s={};const o=(t,e)=>e;class u{constructor(t,e,r){this.name=t,r?this.dispatch=e.setState:this.setState=e.setState,this.getState=(()=>e.state)}}function i(t,e={},r=o){if("string"!=typeof t)throw"store name must be a string";if(s[t])throw"store already exists";const n={state:e,reducer:r,setState(t){this.state=this.reducer(this.state,t),this.setters.forEach(t=>t(this.state))},setters:[]};return n.setState=n.setState.bind(n),n.public=new u(t,n,r!==o),s=Object.assign({},s,{[t]:n}),n.public}function c(t){try{return s[t].public}catch(t){throw"store does not exist"}}function a(t="store"){const e=function(t){const e=t instanceof u?t.name:t;return s[e]}(t);if(!e)throw"store does not exist";const[r,o]=Object(n.useState)(e.state);return Object(n.useEffect)(()=>()=>{e.setters=e.setters.filter(t=>t!==o)},[]),e.setters.includes(o)||e.setters.push(o),[r,e.setState]}}]);
{
"name": "react-hookstore",
"version": "1.0.8",
"version": "1.1.0",
"description": "A state management library for react using the bleeding edge hooks feature",

@@ -9,6 +9,9 @@ "main": "dist/react-hookstore.js",

"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"test": "jest",
"build": "webpack --progress --config webpack.prod.config.js",
"start": "webpack-dev-server --hot --reload --config webpack.dev.config.js"
},
"jest": {
"setupTestFrameworkScriptFile": "<rootDir>/tests-setup.js"
},
"keywords": [

@@ -24,11 +27,17 @@ "react",

"devDependencies": {
"@babel/core": "^7.1.2",
"@babel/plugin-proposal-object-rest-spread": "^7.0.0",
"@babel/preset-env": "^7.1.0",
"@babel/core": "^7.2.2",
"@babel/plugin-proposal-object-rest-spread": "^7.2.0",
"@babel/preset-env": "^7.2.3",
"@babel/preset-react": "^7.0.0",
"@babel/preset-stage-0": "^7.0.0",
"babel-core": "^7.0.0-bridge.0",
"babel-jest": "^23.6.0",
"babel-loader": "^8.0.4",
"enzyme": "^3.8.0",
"enzyme-adapter-react-16": "^1.7.1",
"html-webpack-plugin": "^3.2.0",
"jest": "^23.6.0",
"react": "^16.7.0-alpha.0",
"react-dom": "^16.7.0-alpha.0",
"regenerator-runtime": "^0.13.1",
"webpack": "^4.23.1",

@@ -35,0 +44,0 @@ "webpack-cli": "^3.1.2",

@@ -7,13 +7,28 @@ # React Hook Store

# Table of Contents
- [Installation](#installation)
- Usage
- [Basic](#usage_basic)
- [Namespacing and referencing stores](#usage_namespace)
- [Reducer powered stores](#usage_reducer)
- API
- [createStore](#api_createStore)
- [getStoreByName](#api_getStoreByName)
- [StoreInterface](#api_storeInterface)
- [usStore](#api_useStore)
- [Migrating from v1.0 to v1.1](#migration)
> ⚠️ BREAKING CHANGES: Version 1.1 is not compatible with previous versions. It is easy to update your previous versions' code to work with it, though. [Click here](#migration) to know how.
> ⚠️ Warning: hooks are not part of a stable React release yet, so use this library only for experiments
## Installation
## <a name="installation">Installation</a>
You can install the lib through NPM or grab the files in the `dist` folder of this repository.
`npm install --save react-hookstore`
## Usage
### Basic
## <a name="usage">Usage</a>
### <a name="usage_basic">Basic</a>
This is the most basic implementation of the library. create a store with its initial state.
Later, call `useStore` inside components to retrive its state and setState method.
Later, call `useStore` inside components to retrieve its state and setState method.
The value passed as the first argument to the setState method will be the new state. no reducer required (but you can use a reducer, see the advanced example down below).

@@ -25,7 +40,7 @@

createStore({ state: 1 });
createStore('clickStore', 0);
function StatefullHello() {
// just use the useStore method to grab the state and the setState methods
const [ state, setState ] = useStore();
const [ timesClicked, setClicks ] = useStore('clickStore');

@@ -35,4 +50,4 @@ return (

<h1>Hello, component!</h1>
<h2>The button inside this component was clicked {state} times</h2>
<button type="button" onClick={() => setState(state+1)}>Update</button>
<h2>The button inside this component was clicked {timesClicked} times</h2>
<button type="button" onClick={() => setClicks(timesClicked+1)}>Update</button>
</div>

@@ -54,4 +69,7 @@ );

### Advanced (namespaced and reducer-powered stores)
We can delegate the state management to reducers (just like redux!) if we want, we can also namespace stores if we want to have more than one store per app.
### <a name="usage_namespace">Namespacing and referencing stores</a>
It is possible to create multiple stores in an app.
A string name must be provided at a store creation when multiple stores are created.
Stores can be referenced by using their instance that is returned by the createStore method, as well as using their name.
```javascript

@@ -61,4 +79,34 @@ import React from 'react';

const clickCount = createStore({ state: 1, name: 'clickCountStore'});
createStore({ state: 'John Doe', name: 'nameStore' });
// counter will start at 2
clickCount.setState(2);
function StatefullHello() {
// this line will reference a store by its instance
const [ clicks, setClicks ] = useStore(clickCount);
// this line will reference a store by its name
const [ name ] = useStore('nameStore');
return (
<div>
<h1>Hello, {name}!</h1>
<h2>The button inside this component was clicked {clicks} times</h2>
<button type="button" onClick={() => setClicks(clicks+1)}>Update</button>
</div>
);
}
```
Both methods can be used and mixed according to the needs, but we recomend using the instance identifiers.
### <a name="usage_reducer">Reducer powered stores</a>
We can delegate the state management to reducers (just like redux!) if we want.
```javascript
import React from 'react';
import { createStore, useStore } from 'react-hookstore';
// this one is more complex, it has a name and a reducer function
createStore({
const todoListStore = createStore({
name: 'todoList',

@@ -93,4 +141,3 @@ state: {

function AddTodo() {
// Grab the correct store by specifying its namespace
const [ state: { todos }, dispatch ] = useStore('todoList');
const [ { todos }, dispatch ] = useStore(todoListStore);

@@ -114,4 +161,3 @@ const onSubmit = (e) => {

function TodoList() {
// Grab the correct store by specifying its namespace
const [ state: { todos }, dispatch ] = useStore('todoList');
const [ { todos }, dispatch ] = useStore(todoListStore);
const deleteTodo = id => dispatch({ type: 'delete', payload: id })

@@ -130,14 +176,55 @@ return (

```
## API
### `createStore(config={ state, name, reducer })`
Creates a store to be used across the entire application.
## Methods API
### <a name="api_createStore">`createStore(name:String, state:*, reducer:Function):StoreInterface`</a>
Creates a store to be used across the entire application. Returns a StoreInterface object.
### Arguments
#### `config.state:* = {}`
#### `name:String`
The namespace for your store, it can be used to identify the store across the application.
#### `state:* = {}`
The store's initial state. it can be any data type. defaults to an empty object. Optional
#### `config.name:String = 'store'`
The namespace for your store, it can be used to better identify the store across the application. Optional
#### `config.reducer:Function = null`
#### `reducer:Function = null`
You can specify a reducer function to take care of state changes. the reducer functions receives two arguments, the previous state and the action that triggered the state update. the function must return a new state, if not, the new state will be `null`. Optional
### `useStore(storeName='store')`
### <a name="api_getStoreByName">`getStoreByName(name:String):StoreInterface`</a>
Finds a store by its name and return its instance.
### Arguments
#### `name:String = 'store'`
The name of the store.
## Objects API
### <a name="api_storeInterface">`StoreInterface`</a>
The store instance that is returned by the createStore and getStoreByName methods.
### Interface
#### `name:String`
The name of the store;
#### `getState:Function():*`
A method that returns the store's current state
#### `setState:Function(*)`
Sets the state of the store. works if the store does not use a reducer state handler. Otherwise, use `dispatch`
#### `dispatch:Function(*)`
Dispatchs whatever is passed into this function to the store. works if the store uses a reducer state handler. Otherwise, use `setState`
## React API
### <a name="api_useStore">`useStore(identifier:String|StoreInterface)`</a>
A function that returns a pair with the current state and the handler method for the specified store.
### Arguments
#### Identifier:String|StoreInterface
The store identifier. It can be either its string name or its StoreInterface instance returned by a createStore or getStoreByName method.
# <a name="migration">Migrating from v1.0 to v1.1</a>
- createStore now receives 3 arguments instead of an object with 3 properties.
- the name argument is now required even if only one store is being used.
```javascript
// v0.1
createStore({state: 0});
createStore({
name: 'store',
state: 0,
reducer(state, action) {
return state + action;
}
})
// v0.2
createStore('myStore', 0);
createStore('store', 0, (state, value) => state + action);
```

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc