rematch是對redux的二次封裝,簡化了redux是使用,極大的提高了開發體驗。rematch僅僅是對redux的封裝,沒有依賴redux-saga,也沒有關聯react,因此其可以用在其他的檢視庫中,如vue等。
1. rematch的優點
1.省略了action types
不必再多次寫字串,使用model/method代替
2.省略了action creators
直接呼叫方法,不必再生產action type,使用dispatch.model.method代替
3.省略了switch語句
呼叫model.method方法,不必判斷action type
4.集中書寫狀態,同步和非同步方法
在一個model中使用state,reducers和effects來寫狀態,同步和非同步方法
2. rematch的model
model中直接寫state,reducers,effects,十分集中方便
export const count = { state: 0, // initial state reducers: { // handle state changes with pure functions increment(state, payload) { return state + payload } }, effects: (dispatch) => ({ // handle state changes with impure functions. // use async/await for async actions async incrementAsync(payload, rootState) { await new Promise(resolve => setTimeout(resolve, 1000)) dispatch.count.increment(payload) } }) }
3. rematch的dispatch
dispatch可以直接呼叫同步和非同步方法,不必再傳送action
import { init } from '@rematch/core' import * as models from './models' const store = init({ models, }) export const { dispatch } = store // 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
4. rematch的狀態派發
依然使用redux的connect,mapStateToProps,mapStateToDispatch來派發狀態和方法到子元件
import React from 'react' import ReactDOM from 'react-dom' import { Provider, connect } from 'react-redux' import store from './index' 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') )