All Projects → floating → Restore

floating / Restore

Licence: mit
A predictable & observable state container for React apps

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to Restore

React Eva
Effects+View+Actions(React distributed state management solution with rxjs.)
Stars: ✭ 121 (-9.02%)
Mutual labels:  observable
Wana
Easy observable state for React ⚡️
Stars: ✭ 128 (-3.76%)
Mutual labels:  observable
Minimongoexplorer
Handy Google Chrome extension for reviewing MiniMongo.
Stars: ✭ 131 (-1.5%)
Mutual labels:  devtools
Service Worker Detector
This extension detects if a website registers a Service Worker.
Stars: ✭ 124 (-6.77%)
Mutual labels:  devtools
Check It Out
A command line interface for Git Checkout. See branches available for checkout.
Stars: ✭ 127 (-4.51%)
Mutual labels:  devtools
Devtools Core
🚀 Packages for Firefox DevTools
Stars: ✭ 129 (-3.01%)
Mutual labels:  devtools
Lasca Compiler
Lasca is Scala shifted towards Haskell.
Stars: ✭ 121 (-9.02%)
Mutual labels:  immutability
Pure Store
A tiny immutable store with type safety.
Stars: ✭ 133 (+0%)
Mutual labels:  immutability
Async Sockets Cpp
Simple thread-based asynchronous TCP & UDP Socket classes in C++.
Stars: ✭ 127 (-4.51%)
Mutual labels:  simple
Works For Me
Collection of developer toolkits
Stars: ✭ 131 (-1.5%)
Mutual labels:  devtools
Ndb
ndb is an improved debugging experience for Node.js, enabled by Chrome DevTools
Stars: ✭ 10,581 (+7855.64%)
Mutual labels:  devtools
Built redux
an implementation of redux written in dart that enforces immutability
Stars: ✭ 126 (-5.26%)
Mutual labels:  immutability
Fossurl
Your Own Url Shortner Without any fancy server side processing and support for custom url , which can even be hosted on GitHub Pages
Stars: ✭ 131 (-1.5%)
Mutual labels:  simple
Backup Manager
Database backup manager for dumping to and restoring databases from S3, Dropbox, FTP, SFTP, and Rackspace Cloud
Stars: ✭ 1,589 (+1094.74%)
Mutual labels:  restore
Simplebluetoothlibrary
Android library for simplifying bluetooth usage.
Stars: ✭ 131 (-1.5%)
Mutual labels:  simple
Network Plus
DevTools for network recording, modification and resending.
Stars: ✭ 122 (-8.27%)
Mutual labels:  devtools
Vue Slide Bar
🎢 A Simple Vue Slider Bar Component.
Stars: ✭ 129 (-3.01%)
Mutual labels:  simple
Recovery
Blog:https://zhengxiaoyong.com Wechat:
Stars: ✭ 1,679 (+1162.41%)
Mutual labels:  restore
Hexo Theme Zhaoo
🐳 A simple theme for Hexo
Stars: ✭ 131 (-1.5%)
Mutual labels:  simple
Rxlifecycle
Rx binding of stock Android Activities & Fragment Lifecycle, avoiding memory leak
Stars: ✭ 131 (-1.5%)
Mutual labels:  observable

Restore

A predictable & observable state container for React apps

  • Simple - Reduced boilerplate, minimal interface, refined patterns, ~5kB
  • Observable - Subscriptions to value changes are automatic, eliminating unnecessary renders
  • Predictable - Unidirectional data makes it easy to test, debug and reason about your application
  • Immutable - Frozen state along with thaw/replace updates provide baked in immutability
  • DevTools - Helpful tools, including time travel, provide clear visibility of your state, actions, updates & observers

Restore DevTools

Install

npm install react-restore

Creating a store

A store holds the state of the application and the actions used to update that state

import Restore from 'react-restore'
import * as actions from './actions'
let initialState = {text: 'Hello World'}
let store = Restore.create(initialState, actions)

Now we have a store!

Accessing values in the store

To get the text value from the store

store('text') // 'Hello World'

Updating values in the store

  • actions are used to make updates to the state of the store
  • actions are passed as an object during the store's creation
  • The actions object can be created explicitly or by using import syntax
    • e.g. import * as actions from './actions'
  • actions contain the whole lifecycle of an update making async updates easy to create and track

Let's create an action called setText to update the text value in our store

export const setText = (update, newText) => {
  update(state => {
    state.text = newText
    return state
  })
}

setText can now be called via the store

store.setText('Updated World')

This would update the value text in the store to 'Updated World'

The update method

  • actions are passed update as their first argument (followed by any arguments you passed to them)
  • The update method is how we replace values held by the store
  • The update method uses a pure updater function to perform these updates

If you look back at our setText action you can see our updater function

state => {
  state.text = newText
  return state
}

The updater function is passed the state (or more likely, part of the state) and returns an updated version of it

Targeting state updates

  • update takes a dot notation path as an optional first argument
  • This path allows you to target part of the state instead of the whole state
  • By doing this, only the components that care about what you're targeting will re-render and the rest will not

For example, our setText action could be

export const setText = (update, newText) => {
 update('text', text => {
   return newText
 })
}

Targeting a more complex state

import Restore from 'react-restore'
import * as actions from './actions'
let initialState = {
  nested: {
    wordOne: 'Hello',
    wordTwo: 'World'
  }
}
let store = Restore.create(initialState, actions)

Let's create an action called setNestedText to update wordTwo in our store

export const setNestedText = (update, newValue) => {
  update('nested.wordTwo', wordTwo => newValue)
}

Calling it is the same as before

store.setNestedText('Updated World')

This would update the value of wordTwo from 'World' to 'Updated World'

Multi-arg Paths

Instead of concatenating a string for the path passed to store or update, you can define your path with multiple arguments. For example if you had an id (let id = 123) for an item within the state you could break the path into multiple arguments, like so...

let name = store('items', id, 'name') // Gets the value of items[id].name from the store

// When updating, the last argument is always the updater function
update('items', id, 'name', name => 'bar') // Updates the value of items[id].name to 'bar'

Connecting the store to your React components

Connecting React components to the store is easy

Restore.connect(Component)
  • Once a component is connected, it will have access to the store via this.store
  • It will automatically re-render itself when a value it consumes from the store changes
  • A connected component inherits the store of its closest connected parent
  • At the top-level of your app you will explicitly connect a store, since it has no parent to inherit from
  • This top-level store will be passed down to your other connected components
  • We recommend using a single top-level store for your app
Restore.connect(Component, store) // Explicitly connects store to Component
Restore.connect(Component) // Component inherits store from closest parent Component

To access the store from within a connected component, we do the same as before but this time referencing this.store

this.store('text')
// or
this.store.setText('Updated World')

Async Updates

Actions can contain synchronous and asynchronous updates, both are tracked and attributed to the action throughout its lifecycle. Here we'll make our setText action get the newText value from the server and then update the state asynchronously.

export const setText = update => {
  getTextFromServer(newText => {
    update('text', text => newText)
  })
}

It can be useful to compose synchronous and asynchronous updates together. Say you wanted to show a loading message while you fetched the newText value from the server. You could update a loading flag synchronously and then unset it later when you get the response.

export const setText = update => {
  update('loading', loading => true)
  getTextFromServer(newText => {
    update('loading', loading => false)
    update('text', text => newText)
  })
}

Enabling DevTools / Time Travel

Restore has a <DevTools /> component you can use to observe updates to the state and time travel through past actions

npm install restore-devtools --save-dev
import DevTools from 'restore-devtools'

Drop <DevTools /> anywhere in your application to enable the dev tools

https://github.com/floating/restore-devtools

Standalone Observers

Connected components are observers but you can use this functionality outside of components too!

store.observer(() => {
  console.log(store('text'))
})

This function will run once immediately and again anytime the values it consumes change, in this case our text value

Putting it together

App.jsx

import React from 'react'
import Restore from 'react-restore'

class App extends React.Component {
  render () {
    return (
      <div onClick={() => this.store.setText('Updated World')}>
        {this.store('text')}
      </div>
    )
  }
}

export default Restore.connect(App)

actions.js

export const setText = (update, newText) => {
  update('text', text => {
    return newText
  })
}

index.js

import React from 'react'
import ReactDOM from 'react-dom'
import Restore from 'react-restore'

import App from './App.jsx'
import * as actions from './actions.js'

let initialState = {text: 'Hello World'}
let store = Restore.create(initialState, actions)
let Root = Restore.connect(App, store)

ReactDOM.render(<Root />, document.getElementById('root'))

Projects using Restore

  • Frame - A cross-platform Ethereum interface
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].