| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
A predictable & observable state container for React apps
npm install react-restore
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!
To get the text value from the store
store('text') // 'Hello World'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'
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
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 React components to the store is easy
Restore.connect(Component)Restore.connect(Component, store) // Explicitly connects store to Component
Restore.connect(Component) // Component inherits store from closest parent ComponentTo 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')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)
})
}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
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
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'))| Back | FazBrowse Home | New Git URL |