React state manager based on redux
import { createSiloStore, Provider, connect } from 'silo-react'
const store = createSiloStore()
store.createPath('todos', {
initialState() {
return {
list: [],
}
},
get: {
count: ({ state }) => state.list.length,
},
set: {
add({ state }) {
return {
...state,
list: state.list.concat({ title: `todo title ${state.list.length + 1}`, id: state.list.length })
}
}
},
onSet(payload) {
// payload with tracker
},
action: {
async fetchList({ set }) {
return new Promise(res => setTimeout(() => set.add()), 10)
}
},
})
class Todos extends React.Component {
componentDidMount() {
this.props.action.fetchList()
}
render() {
return <div>
<h2>Todos ({this.props.get.count()})</h2>
<ul>{this.props.state.list.map(item => <li key={item.id}>{item.title}</li>)}</ul>
<button onClick={() => this.props.set.add()}>Add</button>
</div>
}
}
const TodoContainer = connect('todos')(Todos)
ReactDOM.render(
<Provider store={store}>
<TodoContainer />
</Provider>
, document.getElementById('__content'))
const logger = s => next => action => {
console.log(action)
return next(action)
}
const store = createSiloStore({}, applyMiddleware(logger)(createStore))
store.getState('todos') // Get "todos" state
store.exec('action:todos/fetchList', ...params) // exec action with params
store.exec('get:todos/count', ...params) // exec get
store.exec('set:todos/add', ...params) // exec set
const trackerRule = ({ path, type, method }) => `${type}:${path}/${method}`
const store = createSiloStore({}, undefined, trackerRule)
store.createPath('myPath', {
action: {
act1({ action }) {
return action.act2()
},
act2({ action }) {
return action.act3()
},
act3({ tracker }) {
return tracker.records()
}
}
})
expect(store.exec('action:myPath/act1')).toEqual(["action:myPath/act1", "action:myPath/act2", "action:myPath/act3"])
const store = createSiloStore()
store.createPath('myPath', {
action: {
act({ myContext }) {
console.log(myContext) // my context
}
},
injectArgs(defaultArgs) {
return {
...defaultArgs,
myContext: { /* my context */}
}
},
})