1.0.3 • Published 3 years ago

react-named-state v1.0.3

Weekly downloads
-
License
MIT
Repository
github
Last release
3 years ago

react-named-state

  1. Make state shareable without using context
  2. Make state accessible without re-rendering component
  3. Make state extensible using localStorage / sessionStorage (or your own storage)

Demo

CodeSandbox Demo

Install

# Using npm
npm i -S react-named-state
# Using yarn
yarn add react-named-state

Quick Start

import { useLocalStorage, setLocalStorage } from 'react-named-state'

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

keytypedescription
keystringSet a key name to identify what the state is.Synchronize states with the same key.
initialStateanyReturn initialState when the state is undefined.If initialState is a function, return the result of the function call.
storageany[Optional] default storage is a simple object in memory.You can pass any object that has property access.For example, use localStorage to create a persistent state.

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

1. Make state shareable without using context

import { useStorage } from 'react-named-state'

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)} />
}

2. Make state accessible without re-rendering component

import { useStorage, setStorage, getStorage } from 'react-named-state'

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>
  )
}

3. Make state extensible using localStorage / sessionStorage

import { useStorage, useLocalStorage } from 'react-named-state'

function ComponentA() {
  // Make a persistent state
  const [query, setQuery] = useStorage('query', '', localStorage)
  return <input value={query} onChange={event => setQuery(event.target.value)} />
}

function ComponentB() {
  // This is syntax sugar!
  const [query, setQuery] = useLocalStorage('query', '')
  return <input value={query} onChange={event => setQuery(event.target.value)} />
}

You can also use your own custom storage! (advanced usage)

import { useSharedStorage } from 'react-named-state'

const customStorage = new Proxy({}, {
  get: function (storage, key) {
    console.log('get', key) // do something
    return storage[key]
  },
  set: function (storage, key, value) {
    console.log('set', key, value) // do something
    storage[key] = value
    return true
  },
})

function Component() {
  const [query, setQuery] = useStorage('query', '', customStorage)
  return <input value={query} onChange={event => setQuery(event.target.value)} />
}

Happy hacking!