React hooks for managing and creating reusable stateful object patterns.
use-state-api-hooks
has moved toreact-use-object-state!
To upgrade, run:
npm uninstall use-state-api-hooks npm install react-use-object-stateor
yarn remove use-state-api-hooks yarn add react-use-object-stateRemember to also update your import lines to the new package too:
- import { - useStateApi, - useBooleanStateApi, - useArrayStateApi, - useUniqueArrayStateApi, - useCounterStateApi, - useAnchorElStateApi - } from 'use-state-api-hooks'; + import { + useObjectState, + useBooleanState, + useArrayState, + useUniqueArrayState, + useCounterState, + useAnchorElState + } from 'react-use-object-state'
npm install --save use-state-api-hooks
or
yarn add use-state-api-hooks
You can read about the inspiration behind this library here
State API for boolean values (T or F states)
import React from "react";
import { useBooleanStateApi } from "use-state-api-hooks";
const BooleanExample = () => {
const lightSwitch = useBooleanStateApi(false);
return (
<div>
<button onClick={lightSwitch.setTrue} >
Turn on
</button>
<button onClick={lightSwitch.setFalse} >
Turn off
</button>
<button onClick={lightSwitch.toggle} >
Toggle
</button>
<div>The light switch is turned {lightSwitch.state ? "on" : "off"}</div>
</div>
);
};
export default BooleanExample;
Name | Type | Default | Description |
---|---|---|---|
state | Boolean | State of the boolean object | |
setState | Function(state: Boolean): void | Sets the boolean state | |
setTrue | Function(): void | Sets state to true | |
setFalse | Function(): void | Sets state to false | |
toggle | Function(): void | Toggles boolean state |
State API for arrays (array states)
import React from "react";
import { useArrayStateApi } from "use-state-api-hooks";
const mockData = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const ArrayExample = () => {
const list = useArrayStateApi<number>(mockData);
return (
<div>
<button onClick={list.clear} >
Clear
</button>
<button
onClick={() => list.push(list.state.length + 1)}
>
Push
</button>
<button onClick={list.pop} >
Pop
</button>
<button onClick={list.reverse} >
Reverse
</button>
{list.state.map(listItem => (
<div key={listItem}>{listItem} </div>
))}
</div>
);
};
export default ArrayExample;
Name | Type | Default | Description |
---|---|---|---|
state | Array | State of the array object | |
setState | Function(state: Array): void | Sets the array state | |
clear | Function(): void | Empty's the array ([]) | |
reverse | Function(): void | Reverses the array | |
pop | Function(): void | Pops value off of the end of the array (does nothing on empty array) | |
push | Function(...vals: T[]) | Pushes values onto end of the array | |
shift | Function(): void | Removes value from beginning of array (does nothing on empty array) | |
unshift | Function(...vals: T[]) | Pushes values onto beginning of array | |
insertAt | Function(val: T, index: number): void | Inserts value at a given index (Does nothing out of bounds) | |
upsertAt | Function(val: T, index: number): void | Removes value from beginning of array (Does nothing out of bounds) | |
deleteAt | Function(index: number): void | Removes value from beginning of array (Does nothing out of bounds) |
State API for unique arrays (sets)
Name | Type | Default | Description |
---|---|---|---|
state | Array | State of the array object with unique vals | |
setState | Function(state: Array): void | Sets the array state with unique vals | |
clear | Function(): void | Empty's the array ([]) | |
reverse | Function(): void | Reverses the array | |
toggle | Function(...vals: T[]): void | For each val, either adds it to the array if it doesn't exist, or removes it if it already exists | |
pop | Function(): void | Pops value off of the end of the array (does nothing on empty array) | |
push | Function(...vals: T[]) | Pushes unique values onto end of the array | |
shift | Function(): void | Removes value from beginning of array (does nothing on empty array) | |
unshift | Function(...vals: T[]) | Pushes unique values onto beginning of array | |
insertAt | Function(val: T, index: number): void | Inserts unique value at a given index (Does nothing out of bounds or for nonunique vals) | |
upsertAt | Function(val: T, index: number): void | Removes value from beginning of array (Does nothing out of bounds or for nonunique vals) | |
deleteAt | Function(index: number): void | Removes value from beginning of array (Does nothing out of bounds) |
State API for counters
import React from "react";
import { useCounterStateApi } from "use-state-api-hooks";
const CounterExample = () => {
const counter = useCounterStateApi({ min: 0, max: 10, count: 0 });
return (
<div>
<button onClick={counter.increment} >
Increment
</Button>
<button onClick={counter.decrement} >
Decrement
</Button>
<h4>
Count: {counter.count}
</h4>
</div>
);
};
Name | Type | Default | Description |
---|---|---|---|
count | Number | Value of the counter | |
min | Number | Minimum possible value of the counter | |
max | Number | Maximum possible value of the counter | |
setCount | Function(count: Number): void | Sets the counter count | |
setMin | Function(min: Number): void | Sets the counter min | |
setMax | Function(max: Number): void | Sets the counter max | |
increment | Function(): void | Increment the count by 1 (won't go above max) | |
incrementBy | Function(x: Number): void | Increment the count by 'x' (won't go above max) | |
decrement | Function(): void | Decrement the count by 1 (won't go below min) | |
incrementBy | Function(x: Number): void | Decrement the count by 'x' (won't go below min) |
State API for anchor elements (ie a button that opens a menu in its location)
import React from "react";
import { useAnchorElStateApi } from "use-state-api-hooks";
import Button from "@material-ui/core/Button";
import Menu from "@material-ui/core/Menu";
import MenuItem from "@material-ui/core/MenuItem";
const AnchorElExample = () => {
const { anchorEl, setAnchorEl, clearAnchorEl } = useAnchorElStateApi(null);
return (
<div >
<Button onClick={setAnchorEl}>Open Menu</Button>
<Menu
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={clearAnchorEl}
>
<MenuItem onClick={clearAnchorEl}>Profile</MenuItem>
<MenuItem onClick={clearAnchorEl}>My account</MenuItem>
<MenuItem onClick={clearAnchorEl}>Logout</MenuItem>
</Menu>
</div>
);
};
Name | Type | Default | Description |
---|---|---|---|
anchorEl | React.MouseEvent or null | Anchored element | |
setAnchorEl | Function(element: React.MouseEvent or null): void | Sets the anchored element | |
clearAnchorEl | Function(): void | Clears the anchored element (sets anchorEl state to null) | |
setState | Function(state: {count: Number, min: Number, max: Number}): void | Sets the counter state |
In addition to providing some common stateful object patterns, useStateApiHooks
can be used to build your own stateful api's. This library follows compositional factory patterns, where each stateful api has a state api factory describing the state api interface. The useStateApi
hook is a general hook at the base of every state api hook that takes a state api factory as a first argument, and an initial state as a second argument.
useStateApi(<yourStateApiFactory>, <initialState>);
From there, it memoizes the state and state methods, and returns your state api hook.
Below is an example of how you would use useStateApi
to create a boolean stateful object using JS. If you are using TS, here is the source code.
// this is how to create useBooleanStateApi is created using JS
import { useStateApi } from 'use-state-api-hooks';
export const booleanStateApiFactory = (setState) => ({
setTrue: () => setState(true),
setFalse: () => setState(false),
toggle: () => setState(!state)
});
export const useBooleanStateApi = (initialState) => useStateApi(booleanStateApiFactory, initialState);
For scalable architecture, useStateApiHooks
suggests using compositional factory patterns. This will help prevent architectural problems associated with classical inheritance, and will give you decoupled reusable factory methods.
// mammalMethods.js
const play = (state) => {...}
const walk = (state) => {...}
const run = (state) => {...}
// useCatStateApi.js
import { useStateApi } from 'use-state-api-hooks';
import { play, walk, run } from './mammalMethods';
export const catStateApiFactory = (setState) => {
return {
// these are methods imported from mammalMethods.
// setState will pass the state into each function
play: () => setState(play),
walk: () => setState(walk),
run: () => setState(run),
// these are specific cat methods
meow: () => {...}
takeBath: () => {...}
};
};
export const useCatStateApi = (initialState) => useStateApi(catStateApiFactory, initialState);
// useDogStateApi.js
import { useStateApi } from 'use-state-api-hooks';
import { play, walk, run } from './mammalMethods';
export const dogStateApiFactory = (setState) => ({
// these are methods imported from mammalMethods
// setState will pass the state into each function
play: () => setState(play),
walk: () => setState(walk),
run: () => setState(run),
// these are specific dog methods
bark: () => {...}
wagTail: () => {...}
});
export const useDogStateApi = (initialState) => useStateApi(dogStateApiFactory, initialState);
MIT © BenBrewerBowman
This hook is created using create-react-hook.