Security News
RubyGems.org Adds New Maintainer Role
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
react-hookstore
Advanced tools
A state management library for react using the bleeding edge hooks feature
A very simple and small (1k gzipped!) state management lib for React that uses the bleeding edge React's useState
hook.
Which basically means no magic behind the curtains, only pure react APIs being used to share state across components.
Try it on Codesandbox!
⚠️ 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 to know how.
⚠️ Warning: hooks are not part of a stable React release yet, so use this library only for experiments
You can install the lib through NPM or grab the files in the dist
folder of this repository.
npm install --save react-hookstore
This is the most basic implementation of the library. create a store with its initial state.
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).
import React from 'react';
import { createStore, useStore } from 'react-hookstore';
createStore('clickStore', 0);
function StatefullHello() {
// just use the useStore method to grab the state and the setState methods
const [ timesClicked, setClicks ] = useStore('clickStore');
return (
<div>
<h1>Hello, component!</h1>
<h2>The button inside this component was clicked {timesClicked} times</h2>
<button type="button" onClick={() => setClicks(timesClicked+1)}>Update</button>
</div>
);
}
function AnotherComponent() {
// you can name the state whatever you want
const [ timesClicked ] = useStore();
return (
<div>
<h1>Hello, this is a second component, with no relation to the one on the top</h1>
<h2>But it is still aware of how many times the button was clicked: {timesClicked} </h2>
</div>
)
}
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.
import React from 'react';
import { createStore, useStore } from 'react-hookstore';
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.
We can delegate the state management to reducers (just like redux!) if we want.
import React from 'react';
import { createStore, useStore } from 'react-hookstore';
// this one is more complex, it has a name and a reducer function
const todoListStore = createStore({
name: 'todoList',
state: {
idCount: 0,
todos: [{ id: 0, text: 'buy milk' }],
},
reducer(state, action) {
// when a reducer is being used, you must return a new state object
switch action.type {
case 'add':
const id = ++state.idCount;
return {
...state,
todos: [
...todos,
{ id, text: action.payload }
];
}
case 'remove':
return {
...state,
todos: state.todos.filter(todo => todo.id !== action.payload)
}
default:
return todos;
}
}
});
function AddTodo() {
const [ { todos }, dispatch ] = useStore(todoListStore);
const onSubmit = (e) => {
e.preventDefault();
const input = e.target.querySelector('input');
const todo = input.value;
input.value = '';
dispatch({ type: 'add', payload: todo });
}
return (
<form onSubmit={onSubmit}>
<input></input>
<button>Create TODO</button>
</form>
)
}
function TodoList() {
const [ { todos }, dispatch ] = useStore(todoListStore);
const deleteTodo = id => dispatch({ type: 'delete', payload: id })
return (
<ul>
<h2>TODOLIST</h2>
{ todos.map(todo =>
<li key={todo.id}>
{ todo } <button onClick={() => deleteTodo(id)} type="button">X</button>
</li>)
}
</ul>
)
}
createStore(name:String, state:*, reducer:Function):StoreInterface
Creates a store to be used across the entire application. Returns a StoreInterface object.
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
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
getStoreByName(name:String):StoreInterface
Finds a store by its name and return its instance.
name:String = 'store'
The name of the store.
StoreInterface
The store instance that is returned by the createStore and getStoreByName methods.
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
useStore(identifier:String|StoreInterface)
A function that returns a pair with the current state and the handler method for the specified store.
The store identifier. It can be either its string name or its StoreInterface instance returned by a createStore or getStoreByName method.
// 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);
FAQs
A state management library for react using the bleeding edge hooks feature
We found that react-hookstore demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
Security News
Node.js will be enforcing stricter semver-major PR policies a month before major releases to enhance stability and ensure reliable release candidates.
Security News
Research
Socket's threat research team has detected five malicious npm packages targeting Roblox developers, deploying malware to steal credentials and personal data.