美文网首页
dva.js 深入浅出

dva.js 深入浅出

作者: 咕叽咕叽先生 | 来源:发表于2022-07-03 10:12 被阅读0次

    使用场景

    dva 首先是一个基于 redux 和 redux-saga 的数据流方案.

    dva 也是 React 应用框架,同样包装了React-Router,简化了 API,让开发 React 应用更加方便和快捷。

    所以:
    dva = React-Router + Redux + Redux-saga

    快速上手

    1、dva提供了一套自己的脚手架 用于构建一个基于dva的基础框架

        $ npm install dva-cli -g
        $ dva -v
        dva-cli version > 0.9.1
        $ dva new dva-quickstart
    

    2、也可以只使用 dva 单纯的当做一个状态管理工具

        $ npm i dva
        // 普通项目中使用dva
        import dva from 'dva';
        const app = dva();
        app.router(() =>
            <App />
        );
        app.start('#root');
    

    dva(opts)可配置opts有哪些?[1]

    核心概念

    img2.jpg
    State 和 View
    • State:一个对象,保存整个应用状态

      State 是储存数据的地方,收到 Action 以后,会更新数据。

    • View:React 组件构成的视图层

      View 就是 React 组件构成的 UI 层,从 State 取数据后,渲染成 HTML 代码。只要 State 有变化,View 就会自动更新。

    Action
    • Action:用来描述 UI 层事件的一个对象
      {
          type: 'click-submit-button',
          payload: this.form.data
      }
      
    connect
    • connect 方法:一个函数,绑定 State 到 View
      import { connect } from 'dva';
      //函数会返回一个对象,用于建立 State 到 Props 的映射关系。
      function mapStateToProps(state) {
          return { todos: state.todos };
      }
      connect(mapStateToProps)(App);
      //返回一个React 组件,App通常是个最外层的容器组件,相当于在整个项目包了一层state
      
    dispatch
    • Action 处理器:处理同步操作的函数。触发 Action 改变 State
      dispatch({
      type: 'click-submit-button',
      payload: this.form.data
      })
      

      dispatch 方法从哪来?被 connect 的 Component 会自动在 props 中拥有 dispatch 方法。

    Effect
    • Action 处理器;处理异步操作的函数。对象中定义 Generator[2] 函数

      effects:  {
              // 这里定义 Generator 函数【es6】
              // dva 提供多个 effect 函数内部的处理函数,比较常用的是 call 和 put。
              *addAfter1Second(action, { call, put, select }) {
                  // const result = yield call(timeoutfun, action.payload);
                  const result = yield (timeoutfun(action.payload));
                  console.log('我是call 的 result', result);
                  const todos = yield select(state => state.count.todos);//此处count为自定义的namespace值
                  console.log('我是select 的 todos', todos);
                  const newState = yield put({
                      type: 'addTodo',
                      payload: todos
                  });
                  console.log('我是put 的 newState', newState);
              },
          }
      
      • call 用于调用异步逻辑,支持 promise
      • select 用于从 state 里获取数据,返回相应的数据
      • put 用于触发 Action,类似于 dispatch 处理同步逻辑
    Subscription
    • 监听器其中,其中方法名可随意定义。初始化必会自动调用一次,每次变化都会⼀次去调⽤⾥⾯的所有⽅法。
        subscriptions: {
            watch({ dispatch, history }, error) {
                return history.listen(({ pathname, query }) => {
                    console.log(pathname)
                    console.log(query)
                });
            },
            click({ dispatch, history }, error) {
                document.addEventListener('click', () => {  
                     //只要⿏标点击就会dispatch,这⾥的add就是reducers中的⽅法名
                    dispatch({ type: "add" })
                })
            }
        }
    

    Model

    dva 提供 app.model 这个对象,所有的应用逻辑都定义在它上面
    model 是 dva 中最重要的概念。以下是典型的例子:

       {
           namespace: 'count',
           // 初始化值 优先级低于dva() 的 opts.initialState
           state: {
               todos:3000
           },
           reducers: {
               // Action 处理器;处理同步操作的函数,根据 Action,从上一个 State 算出当前 State。
               add(state) { return state + 1 },
               // 往 [] 里添加一个新 todo
               addTodo(state, action) { return {...state, payload:action.payload}; }
           },
           effects:  {
           *addAfter1Second(action, { call, put, select }) {
                   // const result = yield call(timeoutfun, action.payload);
                   const result = yield (timeoutfun(action.payload));
                   console.log('我是call 的 result', result);
                   const todos = yield select(state => state.count.todos);//此处count为自定义的namespace值
                   console.log('我是select 的 todos', todos);
                   const newState = yield put({
                       type: 'addTodo',
                       payload: todos
                   });
                   console.log('我是put 的 newState', newState);
               },
           },
           subscriptions: {
               watch({ dispatch, history }, error) {
                   return history.listen(({ pathname, query }) => {
                       console.log(pathname)
                       console.log(query)
                   });
               },
               click({ dispatch, history }, error) {
                   document.addEventListener('click', () => { 
                        dispatch({ type: "add" })
                   })
               }
           }
       }
    
    • namespace: 当前 Model 的名称。dva可以有多个model 以namespace进行区分调用
    • state: 当前 Model 保存state数据的变量
    • reducers: 处理同步动作,唯一可以修改 state 的地方。由 action 触发。
    • effects:Action 处理器,处理异步动作

    1. ES6 新引入了 Generator 函数,函数内用 yield 标记同步逻辑,函数实例使用 .next()依次调用。从而解决异步问题。

    2. https://dvajs.com/api/#app-dva-opts

    相关文章

      网友评论

          本文标题:dva.js 深入浅出

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