Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

react-localstorage-ts

Package Overview
Dependencies
Maintainers
2
Versions
44
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-localstorage-ts

A small library to wrap browser's localstorage in a functional fashion.

  • 1.2.8
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
540
increased by28.88%
Maintainers
2
Weekly downloads
 
Created
Source

release

react-localstorage-ts

A small layer over the browser's localstorage, fallbacks to an in-memory store if localstorage is not supported by the browser.

Built on io-ts and fp-ts, react-localstorage-ts gives you a standard way to access objects stored locally using io-ts's encoding/decoding abilities.

install

yarn

yarn add react-localstorage-ts fp-ts io-ts monocle-ts newtype-ts

npm

npm install react-localstorage-ts fp-ts io-ts monocle-ts newtype-ts

quick start

To use react-localstorage-ts you have to follow a few simple steps:

First you need to define the list of "storable" items by expanding the StoredItems interface:

// store.ts
import * as t from "io-ts"
export const ThemeFlavour = t.union([t.literal("light"), t.literal("dark")])
export type ThemeFlavour = t.TypeOf<typeof ThemeFlavour>

declare module "react-localstorage-ts" {
    interface StoredItems {
        access_token: string
        theme: ThemeFlavour
    }
}

then you create the hooks to read/write the values you just defined:

// localHooks.ts
import * as t from "io-ts"
import {
  makeDefaultedUseLocalItem,
  makeUseLocalItem,
} from "react-localstorage-ts"
import {ThemeFlavour} from "./store"

export const useThemeFlavour = makeDefaultedUseLocalItem("theme", ThemeFlavour, () => "light")
export const useAccessToken = makeUseLocalItem("access_token", t.string)

then you use them in your react components:

// App.tsx
import * as React from "react"
import * as E from "fp-ts/Either"
import LightThemeApp from "./components/LightThemeApp"
import DarkThemeApp from "./components/DarkThemeApp"
import { useThemeFlavour } from "./localHooks"

const App: React.FC = () => {
  const [theme, setTheme] = useThemeFlavour()
  
  return pipe(
    theme,
    E.fold(
      () => {
        console.error('wrong value stored in localStorage!')
      },
      themeFlavour => {
        switch (themeFlavour) {
          case "light": {
            return <LightThemeApp />
          }
          case "dark": {
            return <DarkThemeApp />
          }
        }
      }
    )
  )
}

export default App

LocalValue

A new data structure is defined for items stored in localstorage, LocalValue. When dealing with a value stored in your localstorage there are three possibilities:

  1. there is no value in your localstorage (optionality).
  2. the value is present, but it is wrong (correctness).
  3. the value is present and it is valid (also correctness).

The structure of LocalValue represent the optionality/correctness dicotomy by using well known contructs, Option and Either:

import * as t from "io-ts"

type LocalValue<V> = O.Option<E.Either<t.Errors, V>>

It also has instances for some of the most common type-classes and you can use it in the same way you usually use your usual fp-ts abstractions:

// LoginLayout.tsx
import * as LV from "react-localstorage-ts/LocalValue"
import { useAccessToken } from "./localHooks"
import { goToLoginPage } from "./router"
import App from "./App"

const LoginLayout: React.FC = ({ children }) => {
  const [token] = useAccessToken()

  React.useEffect(() => {
    if (!LV.isValid) {
      goToLoginPage()
    }
  }, [])
  
  return pipe(
    token,
    LV.fold(() => null, () => null, () => <>{ children }</>),
  )
}

// LoginPage.tsx
import * as LV from "react-localstorage-ts/LocalValue"
import { goToHomePage } from "./router"
import { useAccessToken } from "./localHooks"

const LoginPage: React.FC = ({ children }) => {
  const [token, setToken] = useAccessToken()

  React.useEffect(() => {
    if (LV.isValid) {
      goToHomePage()
    }
  }, [])

  return (
    <Form
      onSubmit={() => api.getToken.then(t => setToken(t))}
    />
  )
}

N.B. when you use makeDefaultedUseLocalItem, you loose the optionality of your value, so you are left with an Either instead of a LocalValue.

defining codecs

creating a custom codec to use with makeUseLocalItem can be a really non-trivial task, that's why we ship the utility codec JSONFromString that can be used to "ease the pain". Here is an example of how you can use it to define a custom codec:

import * as t from "io-ts"
import * as E from "fp-ts/Either"
import { pipe } from "fp-ts/function"
import { JSONFromString, isoJSON } from "react-localstorage-ts/JSONFromString"

const ShapeCodec = t.type({ s: t.string, d: DateFromISOString })
type ShapeCodec = t.TypeOf<typeof ShapeCodec>

const defaultShape: ShapeCodec = {
  s: "foo",
  d: new Date(),
}

export const ShapeCodecFromString = new t.Type<ShapeCodec, string>(
  "ShapeCodecFromString",
  ShapeCodec.is,
  (u, c) => {
    return pipe(
      JSONFromString.validate(u, c),
      E.chain((json) => ShapeCodec.validate(json, c)),
    )
  },
  (v) => {
    return pipe(v, ShapeCodec.encode, isoJSON.wrap, JSONFromString.encode)
  },
)

contributing

to commit to this repository there are a few rules:

  • your commits must follow the conventional commit standard (it should be enforced by husky commit-msg hook).
  • your code must be formatted using prettier.
  • all tests must pass.

release flow

here you can find an explanation of the release flow.

Keywords

FAQs

Package last updated on 08 Mar 2021

Did you know?

Socket

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.

Install

Related posts

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