0.6.0 • Published 6 years ago

rematch-core v0.6.0

Weekly downloads
9
License
ISC
Repository
github
Last release
6 years ago

Rematch

Rethink Redux.

Rematch is Redux best practices without the boilerplate. No more action types, action creators, switch statements or thunks.

Index

Getting Started

npm install @rematch/core

Step 1: Init

init configures your reducers, devtools & store.

index.js

import { init } from '@rematch/core'
import * as models from './models'

const store = init({
  models,
})

For a more advanced setup, see plugins and Redux config options.

Step 2: Models

The model brings together state, reducers, async actions & action creators in one place.

models.js

export const count = {
  state: 0, // initial state
  reducers: {
    // handle state changes with pure functions
    increment(state, payload) {
      return state + payload
    }
  },
  effects: {
    // handle state changes with impure functions.
    // use async/await for async actions
    async incrementAsync(payload, rootState) {
      await new Promise(resolve => setTimeout(resolve, 1000))
      this.increment(payload)
    }
  }
}

See the reducers docs to learn more, including how to trigger actions from other models.

Understanding models is as simple as answering a few questions:

  1. What is my initial state? state
  2. How do I change the state? reducers
  3. How do I handle async actions? effects with async/await

Step 3: Dispatch

dispatch is how we trigger reducers & effects in your models. Dispatch standardizes your actions without the need for writing action types or action creators.

import { dispatch } from '@rematch/core'
                                                  // state = { count: 0 }
// reducers
dispatch({ type: 'count/increment', payload: 1 }) // state = { count: 1 }
dispatch.count.increment(1)                       // state = { count: 2 }

// effects
dispatch({ type: 'count/incrementAsync', payload: 1 }) // state = { count: 3 } after delay
dispatch.count.incrementAsync(1)                       // state = { count: 4 } after delay

Dispatch can be called directly, or with the dispatch[model][action](payload) shorthand.

Examples

import React from 'react'
import ReactDOM from 'react-dom'
import { Provider, connect } from 'react-redux'
import { init } from '@rematch/core'

// State

const count = {
  state: 0, // initial state
  reducers: {
    // handle state changes with pure functions
    increment(state, payload) {
      return state + payload
    }
  },
  effects: {
    // handle state changes with impure functions.
    // use async/await for async actions
    async incrementAsync(payload, rootState) {
      await new Promise(resolve => setTimeout(resolve, 1000))
      this.increment(payload)
    }
  }
}

const store = init({
  models: {
    count
  }
})

// View

const Count = props => (
  <div>
    The count is {props.count}
    <button onClick={props.increment}>increment</button>
    <button onClick={props.incrementAsync}>incrementAsync</button>
  </div>
)

const mapState = state => ({
  count: state.count
})

const mapDispatch = ({ count: { increment, incrementAsync }}) => ({
  increment: () => increment(1),
  incrementAsync: () => incrementAsync(1)
})

const CountContainer = connect(mapState, mapDispatch)(Count)

ReactDOM.render(
  <Provider store={store}>
    <CountContainer />
  </Provider>,
  document.getElementById('root')
)

Migrating From Redux

Moving from Redux to Rematch involves very few steps.

  1. Setup Rematch init with Redux step 1
  2. Mix reducers & models step 2
  3. Shift to models step 3

API

See the @rematch/core API


Like this project? ★ us on Github :)