有用过dva框架么?怎么样?

lifesimple
  • 816

dva 官网
dva 文档
蚂蚁金服antd

蚂蚁金服出的一套基于React Redux的框架,有用过么,现在需要做一个项目架构,自己对React生态系统了解不是很多。

感觉使用的话学习成本要低一些,但是就是不知道可能以后会不会遇到一些坑。有什么建议么?

回复
阅读 22.7k
4 个回答
小俞
  • 8.3k

完成一个简单的异步counter功能,看看redux的实现和dva的实现

redux

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 (
    <div>
      {loading ? <div>loading...</div> : <div>{count}</div>}
      <button onClick={() => fetch(count)}>add</button>
    </div>
  )
};

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的实现

dva

app.js

import React from 'react'
import { connect } from 'dva';

const App = ({fetch, count, loading}) => {
  return (
    <div>
      {loading ? <div>loading...</div> : <div>{count}</div>}
      <button onClick={() => fetch(count)}>add</button>
    </div>
  )
};


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处理,总体来说简化了不少,虽然我没用过,但是建议楼主可以尝试

如果你熟悉 react 一整套技术的话,还是原生的好用,这样封装之后感觉不习惯

lizhaoting
  • 5
新手上路,请多包涵

建议楼主去自己搭建框架,dva封装度太高了,包括saga、不可变数据,可能开发完一个项目还不知道redux到底怎么用

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏