dva model理解

作者: FConfidence | 来源:发表于2018-05-04 10:54 被阅读362次
    1. example.js
    import key from 'keymaster';
    
    export default {
    
      namespace: 'example',
    
      state: {
        count: 0,
        test: 'just have a test'
      },
    
      // Subscriptions 是一种从 源 获取数据的方法,它来自于 elm。
      // 用于订阅一个数据源,然后根据条件 dispatch 需要的 action。
      subscriptions: {
        setup({ dispatch, history }) { // eslint-disable-line
          console.log('setup addEventListener')
        },
        keyEvent({dispatch, history}) {
          console.log('ctrl+up addEventListener')
          key('⌘+up, ctrl+up', () => { dispatch({type:'save', payload: 0, testStr: 'keyup Enter'}) });
        },
      },
      // Effect 被称为副作用,在我们的应用中,最常见的就是异步操作,Effects 的最终流向是通过 Reducers 改变 State。
      // 核心需要关注下 put, call, select。
      effects: {
        * fetch({ payload }, { call, put, select }) { // eslint-disable-line
          console.log('*fetch test')
          yield put({ type: 'save', payload }); // 用户触发action  不带namespace表明是本model中的方法
    
          /*
          const todos = yield select(state => state.todos); // 这边的 state 来源于全局的 state
              select 方法提供获取全局 state 的能力,
              也就是说,在这边如果你有需要其他 model 的数据,则完全可以通过 state.modelName 来获取
    
          yield call(addTodo, todo); // 用于调用异步逻辑,支持 promise 。
    
          yield put({ type: 'add', payload: todo }); // 用于触发 action 。
              这边需要注意的是,action 所调用的 reducer 或 effects 来源于本 model 那么在 type 中不需要声明命名空间,
              如果需要触发其他非本 model 的方法,则需要在 type 中声明命名空间,如 yield put({ type: 'namespace/fuc', payload: xxx });
           */
        },
      },
    
      reducers: {
        // action行为 返回新的数据对象   在其他组件中通过 props.dispatch('namespace/add', {}) 来进行调用
        save(state, action) {
          console.log('save: action: ', action.payload)
          // console.log( { ...state, ...action.payload })
          return Object.assign({}, state, {count: action.payload, test: action.testStr?action.testStr:'just have a async test'});
        },
        add(state, action) {
          console.log(action.type, '+1')
          return { count: state.count + 1, test: state.test }
        },
        minus(state, action) {
          console.log(action.type, '-' + action.payload)
          return { count: state.count - action.payload, test: state.test }
        },
      },
    
    };
    
    1. IndexPage.js
    import React from 'react';
    import { connect } from 'dva';
    import styles from './IndexPage.css';
    import MainLayout from '../components/MainLayout/MainLayout';
    
    function IndexPage(props) {
      return (
        <MainLayout location={props.location}>
          <div className={styles.normal}>
    
            {JSON.stringify(props.example)}
            <button key="add" onClick={() => { props.dispatch({type: 'example/add'})}}>+1</button>
            <button key="minus" onClick={() => { props.dispatch({type: 'example/minus', payload: 2})}}>-2</button>
            <br/>
            <button key="fetch" onClick={() => { props.dispatch({type: 'example/fetch', payload: 100})}}> 异步effect</button>
    
            <h1 className={styles.title}>Yay! Welcome to dva!</h1>
            <div className={styles.welcome} />
            <ul className={styles.list}>
              <li>To get started, edit <code>src/index.js</code> and save to reload.</li>
              <li><a href="https://github.com/dvajs/dva-docs/blob/master/v1/en-us/getting-started.md">Getting Started</a></li>
            </ul>
          </div>
        </MainLayout>
      );
    }
    
    IndexPage.propTypes = {
    };
    
    // 从store中example
    export default connect(   ({example})=> ({example}) )(IndexPage);
    
    1. router.js
    import React from 'react';
    import { Router, Route, Switch } from 'dva/router';
    // import IndexPage from './routes/IndexPage';
    
    // 异步模块加载
    import dynamic from 'dva/dynamic'
    
    function RouterConfig({ history, app }) {
      const IndexPage = dynamic({
        app,
        component: () => import('./routes/IndexPage'),
      });
    
      const UsersPage = dynamic({
        app,
        models: () => [
          import('./models/users'),
        ],
        component: () => import('./routes/UsersPage'),
      });
    
      return (
        <Router history={history}>
          <Switch>
            <Route path="/" exact component={IndexPage} />
            <Route exact path="/users" component={UsersPage} />
          </Switch>
        </Router>
      );
    }
    
    export default RouterConfig;
    
    1. scr/index.js
    import dva from 'dva';
    import './index.css';
    
    import { browserHistory } from 'dva/router';
    import createLoading from 'dva-loading';
    import { message } from 'antd';
    
    
    const ERROR_MSG_DURATION = 3; // 3 秒
    
    // ##dva五部曲
    // 1. Initialize
    const app = dva({
      history: browserHistory,
      onError(e) {
        message.error(e.message, ERROR_MSG_DURATION);
      },
    });
    
    // 2. Plugins  插件的使用 为可选项
    // app.use({});
    app.use(createLoading());
    
    // 3. Model 注册   注册到store上
    app.model(require('./models/example').default);
    
    /*
     也可以使用这种方法注册model
    app.model({
      namespace: 'todos', //model 的 namespace
      state: [], // model 的初始化数据
      reducers: {
        // add 方法就是 reducer,可以看到它其实非常简单就是把老的 state 和接收到的数据处理下,返回新的 state
        add(state, { payload: todo }) {
          return state.concat(todo);
        },
      },
    };
    
     */
    
    // 4. Router  配置 Router
    app.router(require('./router').default);
    
    // 5. Start
    app.start('#root');
    

    5 .webpackrc

    {
      "proxy":
      {
        "/api":
        {
          "target": "http://localhost:3000/",
          "changeOrigin": true,
          "pathRewrite":
          {
            "^/api": ""
          }
        }
      }
    }
    
    1. 参考 https://juejin.im/entry/5852184b128fe1006b5454c6
      https://github.com/dvajs/dva/blob/master/README_zh-CN.md

    相关文章

      网友评论

        本文标题:dva model理解

        本文链接:https://www.haomeiwen.com/subject/xdfdrftx.html