All Projects → gunn → Pure Store

gunn / Pure Store

Licence: mit
A tiny immutable store with type safety.

Programming Languages

typescript
32286 projects

Projects that are alternatives of or similar to Pure Store

Pullstate
Simple state stores using immer and React hooks - re-use parts of your state by pulling it anywhere you like!
Stars: ✭ 683 (+413.53%)
Mutual labels:  hooks, state-management, state
useSharedState
useSharedState is a simple hook that can be used to share state between multiple React components.
Stars: ✭ 0 (-100%)
Mutual labels:  hooks, state-management, state
Redhooks
Predictable state container for React apps written using Hooks
Stars: ✭ 149 (+12.03%)
Mutual labels:  immutability, hooks, state-management
jedisdb
redis like key-value state management solution for React
Stars: ✭ 13 (-90.23%)
Mutual labels:  hooks, state-management, state
atomic-state
A decentralized state management library for React
Stars: ✭ 54 (-59.4%)
Mutual labels:  hooks, state-management, state
eventrix
Open-source, Predictable, Scaling JavaScript library for state managing and centralizing application global state. State manage system for react apps.
Stars: ✭ 35 (-73.68%)
Mutual labels:  hooks, state-management, state
react-cool-form
😎 📋 React hooks for forms state and validation, less code more performant.
Stars: ✭ 246 (+84.96%)
Mutual labels:  hooks, state-management, state
Redux Orm
A small, simple and immutable ORM to manage relational data in your Redux store.
Stars: ✭ 2,922 (+2096.99%)
Mutual labels:  state-management, state, frontend
Use Global Context
A new way to use “useContext” better
Stars: ✭ 34 (-74.44%)
Mutual labels:  hooks, state-management, state
Alveron
Elm & Reason inspired state management for React
Stars: ✭ 57 (-57.14%)
Mutual labels:  state-management, state
Yewdux
Redux-like state containers for Yew apps
Stars: ✭ 58 (-56.39%)
Mutual labels:  state-management, state
Radon
Object oriented state management solution for front-end development.
Stars: ✭ 80 (-39.85%)
Mutual labels:  state-management, state
Swiftdux
Predictable state management for SwiftUI applications.
Stars: ✭ 130 (-2.26%)
Mutual labels:  state-management, state
Svelte Store Router
Store-based router for Svelte
Stars: ✭ 54 (-59.4%)
Mutual labels:  state, frontend
React Composition Api
🎨 Simple React state management. Made with @vue/reactivity and ❤️.
Stars: ✭ 67 (-49.62%)
Mutual labels:  state-management, state
React Context Hook
A React.js global state manager with Hooks
Stars: ✭ 50 (-62.41%)
Mutual labels:  hooks, state-management
Use Substate
🍙 Lightweight (<600B minified + gzipped) React Hook to subscribe to a subset of your single app state.
Stars: ✭ 97 (-27.07%)
Mutual labels:  hooks, state-management
Iostore
极简的全局数据管理方案,基于 React Hooks API
Stars: ✭ 99 (-25.56%)
Mutual labels:  hooks, state
Duix
A State Manager focused on KISS and Pareto's Principle
Stars: ✭ 48 (-63.91%)
Mutual labels:  state-management, state
Pwa Boilerplate
✨ PWA Boilerplate is highly scalable and is designed to help you kick-start your next project 🔭.
Stars: ✭ 82 (-38.35%)
Mutual labels:  hooks, frontend

pure-store

Coverage Status npm bundle size Build Status npm mit typescript

Just edit your app's state.

pure-store is a fast, simple, immutable store that lets you update state directly (i.e. imperatively). It also works excellently with typescript.

Comparison with redux

With React Hooks

pure-store can be used without react, but if you are using react you can use the usePureStore hook. We could create the simple counter from the image above like this:

import createStore from "pure-store/react"

const store = createStore({ count: 0 })

export default ()=> {
  const [state, update] = store.usePureStore()

  return (
    <div>
      Counter: { state.count }
      <a onClick={()=> update({count: count+1})}> + </a>
      <a onClick={()=> update({count: count-1})}> - </a>
    </div>
  )
}

If you use react, then congratulations - you know everything you need to to manage state in your app. Because the data is updated immutably, you can pass pieces of the store's state to your React.memo components and they will re-render only when the data has changed giving you excellent performance.

Without Hooks

To use pure-store without react hooks you need to create a store, and know how to use a couple of methods.

createStore(initialState)

Creates a new store with an initial state. You can create multiple independent stores, although usually one is enough.

import createStore from 'pure-store'

const store = createStore({ count: 0 })

If you're using typescript, you can get type checking and autocompletion automatically with the rest of your pure-store usage:

interface State {
  user: User
  messages: {
    user: User
    text: string
    starred?: boolean
  }[]
  lastMessageAt?: Date
  messageCount: number
}

const state: State = {
  user: getUser(),
  messages: []
}

const store = createStore(state)

state / getState()

Returns the current state from the store.

console.log("last message date:", store.getState().lastMessageAt)

const Messages = ()=> {
  const { user, messages, lastMessageAt } = store.state

  return (
    <div>
      <h3>Messages for {user.name}</h3>
      <ul>
        {
          messages.map(m=> (
            <Message message={m} />
          ))
        }
      </ul>
    </div>
  )
}

update(updater)

Use this anytime you want to update store data. The updater argument can either be an object in which case it works just like react's setState, or it can be a function, in which case it's given a copy of the state which can be modified directly.

store.update({ lastMessageAt: new Date() })

store.update(s=> {
  s.messageCount++
  s.messages.push(message)
  s.lastMessageAt = new Date()
})

subscribe(callback)

To re-render components when you update the store, you should subscribe to the store. The subscribe method takes a callback that takes no arguments. It returns a method to remove that subscription. You can subscribe many times to one store.

The recommended way is to re-render your whole app - pure-store can make this very efficient because immutable state lets you use React.PureComponent classes.

const render = ()=> {
  ReactDOM.render(<App />, document.getElementById('root'))
}

store.subscribe(render)
render()

You could also use forceUpdate within a component e.g.:

class App extends React.Component {
  constructor() {
    store.subscribe(()=> this.forceUpdate())
  }
  //...

bonus: storeFor(getter), updaterFor(getter), and usePureStore(getter)

These methods let you define a subset of the store as a shortcut, so you don't have to reference the whole chain every time.

console.log(store.user.profile.address.city)
store.update(s=> s.user.profile.address.city = "Wellington")

// vs
const addressStore   = store.storeFor(s=> s.user.profile.address)
const addressUpdater = store.updaterFor(s=> s.user.profile.address)

// and then:
console.log(addressStore.state.city)
addressUpdater(a=> a.city = "Wellington")

Which can be useful in larger projects.

Patterns

Actions

Other state management libraries have a concept of using 'actions' and 'action creators' for controlled state updates. You may well find them unnecessary, but if you miss them, you can easily do something similar:

// actions.js
import store from './store'
export function postMessage(text) {
  store.update(s=> {
    s.messages.push({
      user: s.user,
      text
    })
    s.lastMessageAt = new Date()
  })
}

// component.js
  //...
  <button onClick={()=> postMessage(this.props.text)} />
  //...

Persistence

If you want to persist data between sessions, it can be done very simply. You just need a way to serialize and de-serialize your data. If you use only basic data types, you can use JSON.stringify and JSON.parse:

const STORAGE_KEY = "myapp-data"
const storedData = JSON.parse(localStorage.getItem(STORAGE_KEY))

const store = createStore(storedData || getDefaultData())

window.addEventListener("beforeunload", ()=> {
  localStorage.setItem(STORAGE_KEY, JSON.stringify(store.state))
})

Future

pure-store is stable now, and I do not anticipate a need to change the API. The focus for now is improving the documentation.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].