@hlhr202/redox
v0.1.7
Published
[![npm](https://img.shields.io/npm/v/@hlhr202/redox.svg)](https://www.npmjs.com/package/@hlhr202/redox)
Downloads
36
Maintainers
Readme
Redox
Redox is a Redux like React state management library which simulate the functionality of Redux dispatcher but maintaining the state with its auto data binder.
Usage
You must enable transform decorator in babel or set 'experimentalDecorators' true in tsconfig for the usage of connect decorator
connect
accept an option object as following format
{
// `modal` is the modal name, should be unique in `Provider` scope.
modal: 'modalName',
// `initialState` is the initial state of connected component.
// It will be passed as props.
// Can either be native js object, Immutable.js object, or a function which transform its props to an object.
initialState: {
yourStateKey: yourStateValue | (props) => yourStateValue
},
// `reducer` is the state transform functions with return of new state
reducer: {
reducerName: (prevState, action) => nextState
},
// `effects` include the side effects which handle complex asynchronouse procedure
// It should return promise of action
effects: {
functionName: async() => action
}
}
Example 1 - Simple App
import React from 'react'
import ReactDOM from 'react-dom'
import {connect, Provider} from '@hlhr202/redox'
import {Map} from 'immutable'
@connect({
modal: 'count',
initialState: Map({
count: 0
}),
reducer: {
inc: (state, action) => state.update('count', count => count + 1),
dec: (state, action) => state.update('count', count => count - 1)
}
})
class Counter extends React.PureComponent {
handleClick = type => {
const action = {type, modal: 'count'}
this.props.dispatch(action)
}
render() {
return (
<div>
<button onClick={this.handleClick.bind(this, 'dec')}>-</button>
{this.props.state.get('count')}
<button onClick={this.handleClick.bind(this, 'inc')}>+</button>
</div>
)
}
}
ReactDOM.render(
<Provider>
<Counter />
</Provider>,
document.getElementById('root')
)
Example 2 - Initialize state with props
import React from 'react'
import ReactDOM from 'react-dom'
import {connect, Provider} from '@hlhr202/redox'
import {Map} from 'immutable'
@connect({
modal: 'App',
initialState: ({display}) => Map({display}),
reducer: {
toggle: state => state.update('display', display => !display)
}
})
class Toggle extends React.PureComponent {
handleClick = () => this.props.dispatch({modal: 'App', type: 'toggle'})
render() {
return (
<div>
<button onClick={this.handleClick}>ToggleButton</button>
{this.props.state.get('display') && <div>Toggled!</div>}
</div>
)
}
}
ReactDOM.render(
<Provider>
<Toggle display={true} />
</Provider>,
document.getElementById('root')
)
Example 3 - Side effects
import React from 'react'
import ReactDOM from 'react-dom'
import {connect, Provider} from '@hlhr202/redox'
import {Map} from 'immutable'
@connect({
modal: 'Article',
initialState: Map({
id: 0,
body: '',
title: ''
}),
reducer: {
fetch: (state, action) => {
const {payload: {body, id, title}} = action
return state.set('id', id).set('body', body).set('title', title)
}
}
effects: {
fetchData: async() => {
const myFetch = await fetch('https://jsonplaceholder.typicode.com/posts/1')
const json = await myFetch.json()
return {
modal: 'Article',
type: 'fetch',
payload: json
}
}
}
})
class Effect extends React.PureComponent {
render() {
return (
<div>
<button onClick={() => this.props.fetchData()}>Fetch</button>
<section>
<div>title: {this.props.state.get('title')}</div>
<div>id: {this.props.state.get('id')}</div>
<div>body: {this.props.state.get('body')}</div>
</section>
</div>
)
}
}
ReactDOM.render(
<Provider>
<Effect/>
</Provider>,
document.getElementById('root')
)