dva 官网
dva 文档
蚂蚁金服antd
蚂蚁金服出的一套基于React Redux的框架,有用过么,现在需要做一个项目架构,自己对React生态系统了解不是很多。
感觉使用的话学习成本要低一些,但是就是不知道可能以后会不会遇到一些坑。有什么建议么?
完成一个简单的异步counter功能,看看redux的实现和dva的实现
actions.js,用setTimeout模拟后端请求
export const REQUEST_TODO = 'REQUEST_TODO';
export const RESPONSE_TODO = 'RESPONSE_TODO';
const request = count => ({type: REQUEST_TODO, payload: {loading: true, count}});
const response = count => ({type: RESPONSE_TODO, payload: {loading: false, count}});
export const fetch = count => {
return (dispatch) => {
dispatch(request(count));
return new Promise(resolve => {
setTimeout(() => {
resolve(count + 1);
}, 1000);
}).then(data => {
dispatch(response(data));
});
}
};
reducer.js
import { REQUEST_TODO, RESPONSE_TODO } from './actions';
export default (state = {
loading: false,
count: 0
}, action) => {
switch (action.type) {
case REQUEST_TODO:
return {...state, ...action.payload};
case RESPONSE_TODO:
return {...state, ...action.payload};
default:
return state;
}
};
app.js
import React from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import * as actions from './actions';
const App = ({fetch, count, loading}) => {
return (
<p>
{loading ? <p>loading...</p> : <p>{count}</p>}
<button onClick={() => fetch(count)}>add</button>
</p>
)
};
function mapStateToProps(state) {
return state;
}
function mapDispatchToProps(dispatch) {
return bindActionCreators(actions, dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps)(App);
main.js
import { render } from 'react-dom';
import { createStore, applyMiddleware } from 'redux';
import { Provider } from 'react-redux'
import thunkMiddleware from 'redux-thunk';
import reducer from './app/reducer';
import App from './app/app';
const store = createStore(reducer, applyMiddleware(thunkMiddleware));
render(
<Provider store={store}>
<App/>
</Provider>
,
document.getElementById('app')
);
使用redux需要拆分action和reducer,实现一个异步流程略繁琐,在看看dva的实现
app.js
import React from 'react'
import { connect } from 'dva';
const App = ({fetch, count, loading}) => {
return (
<p>
{loading ? <p>loading...</p> : <p>{count}</p>}
<button onClick={() => fetch(count)}>add</button>
</p>
)
};
function mapStateToProps(state) {
return state.demo;
}
function mapDispatchToProps(dispatch) {
return {
fetch(count){
dispatch({type: 'demo/fetch', count});
}
}
}
export default connect(mapStateToProps, mapDispatchToProps)(App);
model.js
export default {
namespace: 'demo',
state: {
loading: false,
count: 0
},
reducers: {
request(state, payload) {
return {...state, ...payload};
},
response(state, payload) {
return {...state, ...payload};
}
},
effects: {
*'fetch'(action, {put, call}) {
yield put({type: 'request', loading: true});
let count = yield call((count) => {
return new Promise(resolve => {
setTimeout(() => {
resolve(count + 1);
}, 1000);
});
}, action.count);
yield put({
type: 'response',
loading: false,
count
});
}
}
};
main.js
import dva from 'dva';
import model from './model';
import App from './app';
const app = dva();
app.model(model);
app.router(() => <App />);
app.start('#app');
dva将action和reducer封装到model当中,异步流程采用Generator处理,总体来说简化了不少,虽然我没用过,但是建议楼主可以尝试