README
react-rambo
New way of simple application development with React and Redux!
Table Of Contents
Installation
npm
npm install react-rambo
yarn
yarn add react-rambo
Blocks
Blocks
is a new way of simple application development with React and Redux.
Old way (without Blocks
): :disappointed_relieved:
// actions.js
function startFetchingUserList() {
return { type: 'users.list.start' }
}
function finishFetchingUserList(payload) {
return { type: 'users.list.finish', payload }
}
// reducer.js
const initialState = {
users: { list: { loading: false, value: null } }
}
function reducer(state = initialState, action) {
switch (action.type) {
case 'users.list.start':
state.users.list = { ...state.users.list, loading: true }
return { ...state }
case 'users.list.finish':
state.users.list = { ...state.users.list, loading: false, value: action.payload }
return { ...state }
default:
return state
}
}
// some.js
fetchUser(params) {
return (dispatch, getState) => {
dispatch(startFetchingUserList())
return fetch('https://reqres.in/api/users').then(
response => response.json()
).then(json => dispatch('finish', json.data))
}
}
// SomeComponent.js
...
const mapStateToProps = (state) => ({
userList: state.users.list,
})
const mapDispatchToProps = (dispatch) => ({
getUserList: bindActionCreators(fetchUser, dispatch),
})
...
New way (with Blocks
): :blush:
import { block } from 'react-rambo'
const UserListBlock = block({
name: 'UserList',
initialState: { loading: false, value: null },
reducer: {
start: (state, action) => ({ ...state, loading: true }),
finish: (state, action) => ({ ...state, loading: false, value: action.payload }),
},
methods: {
get: (params) => (dispatch, getState) => {
dispatch('start')
return fetch('https://reqres.in/api/users').then(
response => response.json()
).then(json => dispatch('finish', json.data))
},
},
})
// SomeComponent.js
...
const mapStateToProps = (state) => ({
userList: state.users.list,
})
const mapDispatchToProps = (dispatch) => ({
getUserList: bindActionCreators(UserListBlock.get, dispatch),
})
...
And now:
- All in one file.
- Less code.
- Easier.
dispatch('start')
can be written down like dispatch('#UserList.start')
.
index.js with combineReducers
import { applyMiddleware, combineReducers, createStore } from 'redux'
import thunk from 'redux-thunk'
const rootReducer = combineReducers({
users: combineReducers({
list: UserListBlock._reducer,
}),
})
const store = createStore(rootReducer, {}, applyMiddleware(thunk))
ReactDOM.render(
<Provider store={store}><SomeComponent /></Provider>,
document.getElementById('root'),
)
Dynamic Blocks
Example:
// blocks.js
import { dynamicBlock } from 'react-rambo'
const BannerListBlock = dynamicBlock({
name: 'BannerList',
initialState: { loading: false, value: null },
index: 'type', // is an important parameter
reducer: {
start: (state, action) => ({ ...state, loading: true }),
finish: (state, action) => ({ ...state, loading: false, value: action.payload }),
},
methods: {
get: (params) => ((dispatch, getState) => {
dispatch('start')
return new Promise(resolve => {
setTimeout(() => {
dispatch('finish', 'TEST')
resolve()
}, 1000)
})
}),
},
})
// MyComponent.js
class MyComponent extends Component {
componentDidMount() {
this.props.getBanner({ type: 'left' }) // A index (`type` in this case) must be present in the arguments.
this.props.getBanner({ type: 'right' })
}
render() {
const { banners } = this.props
return <div>
Left banner: {banners.left ? (banners.left.loading ? 'Loading...' : banners.left.value) : '---'}<br/>
Right banner: {banners.right ? (banners.right.loading ? 'Loading...' : banners.left.value) : '---'}<br/>
</div>
}
}
const mapStateToProps = (state) => ({
banners: state.banners,
})
const mapDispatchToProps = (dispatch) => ({
getBanner: bindActionCreators(BannerListBlock.get, dispatch),
})
export default connect(mapStateToProps, mapDispatchToProps)(MyComponent)
Examples
License
MIT