A simple framework based on typescript, redux, redux-saga, redux-action.
npm install resa --save yarn add resa - No redundant redux boilerplate code
- Full IntelliSense with vscode and typescript
- Typed redux store
- Typed action creater and payload
- Better side effects control with redux-saga
- Action creater born to be promise
- Better error handling, support use promise.catch to capture error
- auto detect dependence of state, without mapStateToProps, more easy than connect of react-redux
- Easy learn, easy write, easy test
Actually i like redux and redux-saga very much, but both them have many problems and they are not completely solved by existing packages like dva, mirror:
- Boilerplate code is everywhere when using redux, react-redux, redux-saga, redux-actions in the big project
- no IntelliSense
- no Type-safe
- terrible error handling in redux-saga
We hava integrated redux-devtool in online-vscode, you can click Open in New Window button and open chrome redux-devtool to see what action will be dispathed when you click button.
Define model
// AppModel.ts import { Model, reducer, init, effect } from 'resa'; import { delay } from 'redux-saga'; interface AppState { count: number; } @init<AppState>({ name: 'appModel', namespace: 'namespace', state: { count: 0 // type check here } }) export default class AppModel extends Model<AppState> { @effect() // define saga: async action handle * addAsync(count: number) { yield delay(2000); this.add(count); // type check here } @reducer() // define redux reducer: sync action handle add(count: number) { return { count: this.state.count + count, // type check here }; } } Define component
// App.tsx import * as React from 'react'; import AppModel from './AppModel'; import { subscribe, wapper } from 'resa'; interface AppProps { appModel: AppModel; // annotation type, will inject by subscribe } class App extends React.Component<AppProps> { render() { return ( <div className="App"> <h1>{this.props.appModel.state.count}</h1> {/* add and addAsync have been transformed to action creaters, you just call them with arguments(type check payload) */} <button onClick={() => this.props.appModel.add(1)}>+</button> {/* type check here */} <button onClick={() => this.props.appModel.addAsync(2)}>async</button> {/* type check here */} <button onClick={() => wapper(this.props.appModel.addAsync(2)).then(() => { alert('callback'); }) }> promise </button> </div> ); } } const NewApp = subscribe({ appModel: AppModel })(App); export default NewApp; wapper with Provider like react-redux
import createResa, { Provider } from 'resa'; import App from './App'; const app = createResa(); ReactDOM.render( <Provider resa={app}> <App /> </Provider>, document.getElementById('root') as HTMLElement ); So, do you like the simplicity ?
resa = a simple way to use redux and redux-saga
Pull requests and stars are always welcome. For bugs and feature requests, please create an issue.