0.4.0 • Published 5 years ago
react-cherry v0.4.0
react-cherry
A simple way to use react with react-redux, redux-saga. Keep most things in one file(called model) like Dva.
Feature
- Reducers and sagas in one file.
- Namespace for state.
- Key as action types. (Convenient)
- HMR everywhere. (need extra code snippets)
- Easily used with create-react-app.
How it works
It is a combination and encapsulation of react-redux and redux-saga, aiming to simplify code and related files.
Install
npm i --save react-cherry
Usage with create-react-app
Init a demo project
create-react-app react-cherry-demo
and cd to src
directory.
Modify entry./index.js
- import React from 'react';
- import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
+ import plantCherry from 'react-cherry';
+ import models from './models';
+
+ const cherry = plantCherry(App, document.getElementById('root'), models);
+
+ // enable HMR
+ if (module.hot && process.env.NODE_ENV !== 'production') {
+ module.hot.accept('./App', () => {
+ cherry.updateApp(App);
+ })
+
+ module.hot.accept('./models', () => {
+ cherry.updateModels(models);
+ })
+ }
- ReactDOM.render(<App />, document.getElementById('root'));
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();
Add ./models/index.js
export const models = [{
namespace: 'app',
state: {
count: 0,
},
reducers: {
update: (state, action) => {
return {
...state,
...action.payload,
};
},
},
effects: {
*increaseAsync(action, { call, put, select }) {
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
yield call(delay, 1000);
const count = yield select(state => state.app.count);
yield put({
type: 'update',
payload: {
count: ++count,
}
});
}
}
}];
Modify ./App.js
import React, { Component } from 'react';
+import { connect } from 'react-redux';
import logo from './logo.svg';
import './App.css';
class App extends Component {
+ increaseAsync = () => {
+ this.props.dispatch({
+ type: 'app/increaseAsync',
+ })
+ }
render() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React with redux, redux-saga
</a>
+ <button onClick={this.increaseAsync}>Click</button>
+ <div>Count: {this.props.count}</div>
</header>
</div>
);
}
}
-export default App;
+export default connect(state => ({
+ ...state.app,
+}))(App);