dvajs Model几个疑问?️

1、一个页面配置几个Model是根据什么?
2、dva文档说effects里不直接修改state,请问是在dispatch里传键名,effects接收后填到state吗?
3、我以为的dva的概念大概是,UI事件、网络回调,都会触发action,最后驱动组件更新,但现在是model通过props传入组件
4、dvajs到底提供了什么?

看我下面的代码,这样有违effects里不直接修改state吗?

dispatch({
    type: 'argumentSettingModels/query',
    payload: {
        targetObject: 'paramGroup',
        pl: {
            entityId: '600040',
            beginIndex: 0,
            pageCount: 10,
        }
    }
})

*query({ payload }, { select, call, put }) {
    const { targetObject, pl } = payload
    const state = yield select(({ argumentSettingModels }) => argumentSettingModels)
    const data = yield call(query, pl)
    const map = new Map()
    if (data && data.code === '1000') {
        map.set(targetObject, {
            list: data.list,
            total: data.total,
            beginIndex: pl.beginIndex,
            pageCount: pl.pageCount,
            orderString: pl.orderString,
        })
        yield put({
            type: 'ajxSuccess',
            payload: Object.assign(state, strMapToObj(map))
        })
    }
    else {
        message.error(data.messages, 1)
    }
},
阅读 4.5k
2 个回答

谢邀!

dva设计动机

用过redux都知道,redux设计思想极好,但学习概念很多,晦涩难懂,不利于初学者,并且开发过程中,牵一发而动全身,往往改一个小地方,需要在 reducer, saga, action 之间来回切换 ,因此支付宝前端团队才写的dva。

dva概念

dva 是基于现有应用架构 (redux + react-router + redux-saga 等)的一层轻量封装,没有引入任何新概念!说白了,dva就是为了解决redux现有问题(比如概念多,编写繁琐。。。)而设计的库。您可以把它理解成jquery对js的封装!

model方法

dva核心就是 model 方法,用于把 reducer, initialState, action, saga 封装到一起,其中Model是相关业务操作集合体,是面向业务的一个拆分,因此Model叫做domain model(业务模型)更合理些。一般情况model都按照功能模块划分,就比如公司项目A,这个项目包含用户模块、产品模块、活动模块, 那您就可以拆分成三个Model,分别为user.js、product.js、activitie.js,如果其中一个模块过于庞大您可以再细分,具体依据自己的业务!

dva开发流程

当用户交互改变数据时会通过 dispatch 发起一个 action,同步行为会直接通过 reducers 改变 state ,异步行为则先触发 effects 然后再通过 reducers 改变 state,其中 dispatch 是在组件 connect models以后,通过 props 传入的。该设计思路基本跟开源社区保持一致,现在我们举例说明下dva开发流程,同步行为,异步行为都有:

/**
* 这是user组件(Component)
*/
// ES7新标准:装饰器(Decorator)
@connect(state => ({
    user: state.user,
}))

// 如果您不喜欢ES7装饰器,那好办,我就帮您写一个不用的
export default connect(state => ({
    user: state.user,
}))(User);

// 如果不喜欢ES7装饰器,就不要加export default
export default class User extends Component {
    componentDidMount() {
        const { dispatch } = this.props;
        // 获取数据,异步行为
        dispatch({
          type: 'user/fetch',
        });
    }
    componentWillUnmount() {
        const { dispatch } = this.props;
        // 清空数据,同步行为
        dispatch({
          type: 'user/clear',
        });
    }
    render() {
        const { user } = this.props;
        // 获取到数据了,我要展示到页面上
        const { userData, } = user;
        return (
            <div>
              用户数据:{userData}
            </div>
        )
    }
}

/**
* 这是user model(Model)
*/
export default {
    namespace: 'user',
    state: {
        userData: [],
    },

    effects: {
        *fetch(_, { call, put }) {
            // fetchUserData为获取user数据的函数
            const response = yield call(fetchUserData);
            yield put({
                type: 'save',
                payload: response,
            });
        },
    },

  reducers: {
      save(state, { payload }) {
          return {
              ...state,
              ...payload,
          };
      },
      clear() {
          return {
              userData: [],
          };
      },
  },
};

1.我们建议一个模块一个modal,可以用router来划分,也就是一个router一个modal
2.effects不直接修改state, effects通过put reducerupdata state. dispatch 一个effect后,需要put reducerupdate state.
3.modelstate是通过reduxconnect来提供给组件的。 export default connect(state => state)(/*your component*/)
4.dva其他就是redux与redux-saga、react-router的集成。一个好用的state管理工具。

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