react-rambo

New way of simple application development with React and Redux!

Usage no npm install needed!

<script type="module">
  import reactRambo from 'https://cdn.skypack.dev/react-rambo';
</script>

README

react-rambo

react-rambo

New way of simple application development with React and Redux!

NPM Scrutinizer Code Quality Build Status GitHub Issues Gitter License


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'),
)

back to top


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)

back to top


Examples

License

MIT