app.model可以有多个

  1. import dva, { connect } from './dva'
  2. const app = dva();
  3. app.model({
  4. namespace: 'counter',
  5. state: { number: 0 },
  6. // 同步的方法
  7. reducers: {
  8. // state是之前的状态,return返回值是新状态 state
  9. add(state, action) {
  10. return { number: state.number + (action.payload || 10) }
  11. },
  12. minus(state) {
  13. return { number: state.number - 2 }
  14. }
  15. },
  16. })
  17. app.model({
  18. namespace: 'list',
  19. state: { number: 0 },
  20. // 同步的方法
  21. reducers: {
  22. // state是之前的状态,return返回值是新状态 state
  23. add(state, action) {
  24. // eslint-disable-next-line no-console
  25. console.log('action123', action)
  26. return { number: state.number + (action.payload || 10) }
  27. },
  28. minus(state) {
  29. return { number: state.number - 2 }
  30. }
  31. },
  32. })
  33. app.model({
  34. namespace: 'detail',
  35. state: { number: 0 },
  36. // 同步的方法
  37. reducers: {
  38. // state是之前的状态,return返回值是新状态 state
  39. add(state, action) {
  40. // eslint-disable-next-line no-console
  41. console.log('action123', action)
  42. return { number: state.number + (action.payload || 10) }
  43. },
  44. minus(state) {
  45. return { number: state.number - 2 }
  46. }
  47. },
  48. })

createReducers

createReducers,把 app.model里面的 reducers转成 react-redux中的 reducers函数
app._models = [{namespace: ‘counter’,state, reducers}, {namespace: ‘list’}]
createReducers需要结合 dva.js理解

  1. import { combineReducers, createStore } from 'redux';
  2. function getReducers(app) {
  3. const rootReducers = {};
  4. for (const model of app._models) {
  5. const { namespace, reducers = {}, state : initState = {} } = model;
  6. rootReducers[namespace] = (state = initState, action) => {
  7. const reducer = reducers[action.type];
  8. // 判断函数是否存在,不存在是 undefined
  9. return reducer ? reducer(state, action) : state;
  10. };
  11. }
  12. return combineReducers(rootReducers);
  13. }

dva.js

  1. import React from 'react';
  2. import ReactDOM from 'react-dom';
  3. import { combineReducers, createStore } from 'redux';
  4. import { Provider, connect } from 'react-redux';
  5. import { createHashHistory } from 'history';
  6. function dva(options={}) {
  7. const app = {
  8. model, // 添加模型的方法,方法处理器
  9. router,
  10. start,
  11. _models: [], // 定义所有的模型
  12. _router: undefined, // 存放路由定定义的函数
  13. }
  14. // 把 app.model放到数组里
  15. function model(model) {
  16. const prefixModel = prefixNamespace(model);
  17. app._models.push(prefixModel);
  18. // app._models.push(model);
  19. }
  20. // 路由配置
  21. function router(routerConfig) {
  22. app._router = routerConfig
  23. }
  24. function start(containerId) {
  25. const history = options.history || createHashHistory();
  26. const reducers = createReducers(app); // reducers
  27. const store = createStore(reducers);
  28. // application实例,路由传入默认参数
  29. const App = app._router({ ...app, history })
  30. ReactDOM.render(
  31. <Provider store={store}>{ App }</Provider>,
  32. document.querySelector(containerId)
  33. )
  34. }
  35. return app
  36. }
  37. export { connect }
  38. export default dva
  39. function createReducers(app) {
  40. const rootReducers = {};
  41. // app._models = [{namespace: 'counter',state, reducers}, {namespace: 'list'}]
  42. for(const model of app._models) {
  43. const { namespace, reducers = {} } = model;
  44. rootReducers[namespace] = (state = model.state, action) => {
  45. const reducer = reducers[action.type]
  46. return reducer ? reducer(state, action) : state;
  47. }
  48. }
  49. return combineReducers(rootReducers);
  50. }
  51. // 此方法就是把 reducers对象的属性从 add 变成 'counter/add'
  52. function prefixNamespace(model, delimit = '/') {
  53. const { reducers, namespace } = model;
  54. const keys = Object.keys(reducers);
  55. window.console.log(23, model)
  56. // 返回新的 reducers 'counter/add'
  57. model.reducers = keys.reduce((memo, key) => {
  58. const reducerKey = `${namespace}${delimit}${key}`;
  59. memo[reducerKey] = reducers[key];
  60. return memo;
  61. }, {});
  62. return model;
  63. }