@rpgtec/use-storage
Make state shareable
without using contextMake state persistent
using localStorageMake state accessible
without re-rendering componentMake state extensible
using your own custom storage
Demo
Installation
# Using npm
npm i -S @rpgtec/use-storage
# Using yarn
yarn add @rpgtec/use-storage
Quick Start
import { useLocalStorage, setLocalStorage } from '@rpgtec/use-storage'
function App() {
// Set the key name as the first argument
const [count, setCount] = useLocalStorage('count', 0)
return (
<div>
{/* Usage is almost the same as setState */}
<div>count: {count}</div>
<button onClick={() => setCount(count + 1)}>Increment</button>
<button onClick={() => setCount(0)}>Reset</button>
{/* The state is remembered even if you reload */}
<button onClick={() => window.location.reload()}>Reload</button>
</div>
)
}
// You can access the state without dependencies
setInterval(() => setLocalStorage('count', x => x + 1), 1000)
Interface
const [state, setState] = useStorage(key, initialState, storage)
Returned value
The usage of state
and setState
is almost the same as that of useState
Arguments
name | type | description |
---|---|---|
key | string |
Set a key name to identify what the state is. Synchronize states with the same key. |
initialState | any |
Return initialState when the state is undefined. If initialState is a function , return the result of the function call. |
storage | object |
[Optional] default storage is a wrapper of simple object in memory. You can also use your own custom storage. |
API
useStorage(key, initialState, storage)
getStorage(key, initialState, storage)
setStorage(key, value, storage)
useLocalStorage(key, initialState)
getLocalStorage(key, initialState)
setLocalStorage(key, value)
useSessionStorage(key, initialState)
getSessionStorage(key, initialState)
setSessionStorage(key, value)
Usage
Make state shareable
without using context
1. import { useStorage } from '@rpgtec/use-storage'
function ComponentA() {
// Set the key name as the first argument
const [query, setQuery] = useStorage('query', '')
return <input value={query} onChange={event => setQuery(event.target.value)} />
}
function ComponentB() {
// Synchronize states with the same key
const [query, setQuery] = useStorage('query', '')
return <input value={query} onChange={event => setQuery(event.target.value)} />
}
Make state persistent
using localStorage
2. import { useLocalStorage } from '@rpgtec/use-storage'
function ComponentA() {
// To make a persistent state, use useLocalStorage instead of useStorage
const [query, setQuery] = useLocalStorage('query', '')
return <input value={query} onChange={event => setQuery(event.target.value)} />
}
function ComponentB() {
// A persistent state is also synchronized with the state of the same key
// And, state is remembered even if you reload
const [query, setQuery] = useLocalStorage('query', '')
return <input value={query} onChange={event => setQuery(event.target.value)} />
}
Make state accessible
without re-rendering component
3. import { useStorage, setStorage, getStorage } from '@rpgtec/use-storage'
function CountView() {
console.log('Render: CountView') //=> re-render when the count is updated
const [count] = useStorage('count', 0)
return <div>count: {count}</div>
}
// No need to re-render this component when the count is updated.
// So, use setStorage / getStorage instead of useStorage.
function CountTool() {
console.log('Render: CountTool') //=> only first rendering
return (
<div>
<button onClick={() => setStorage('count', x => x + 1)}>count up</button>
<button onClick={() => setStorage('count', 0)}>count reset</button>
<button onClick={() => console.log(getStorage('count'))}>get count</button>
</div>
)
}
Make state extensible
using your own custom storage
4. import { useStorage } from '@rpgtec/use-storage'
// Storage must have get / set methods
const numberOnlyStorage = (obj => ({
get: key => {
return obj[key]
},
set: (key, value = '') => {
// Convert value to numbers only!
obj[key] = value.replace(/[^0-9]/g, '').replace(/^0+([0-9])/, '$1') || '0'
return obj[key]
},
}))({})
function Component() {
const [number, setNumber] = useStorage('number', '0', numberOnlyStorage)
return <input value={number} onChange={event => setNumber(event.target.value)} />
}
Happy hacking!