Dva.js總結

1.why Dva

dva 是基於現有應用架構 (redux + react-router + redux-saga 等)的一層輕量封裝,沒有引入任何新概念,所有代碼不到 100 行。dva 實現上儘可能不建立新語法,而是用依賴庫自己的語法,好比 router 的定義仍是用 react-router 的 JSX 語法的方式(dynamic config 是性能的考慮層面,以後會支持)。
他最核心的是提供了 app.model 方法,用於把 reducer, initialState, action, saga 封裝到一塊兒
app.model({
  namespace: 'products',
  state: {//State 表示 Model 的狀態數據
    list: [],
    loading: false,
  },
  subscriptions: [
    function(dispatch) {
      dispatch({type: 'products/query'});//觸發 action 的函數,action 是改變 State 的惟一途徑
    },
  ],
  effects: {//Effect 被稱爲反作用,在咱們的應用中,最多見的就是異步操做
    ['products/query']: function*() {
      yield call(delay(800));
      yield put({
        type: 'products/query/success',
        payload: ['ant-tool', 'roof'],
      });
    },
  },
//在dva中reducers聚合積累的結果是當前model的state 對象。經過actions中傳入的值,
//與當前 reducers 中的值進行運算得到新的值(也就是新的 state)
  reducers: {
    ['products/query'](state) {
      return { ...state, loading: true, };
    },
    ['products/query/success'](state, { payload }) {
      return { ...state, loading: false, list: payload };
    },
  },
});

2.簡單明瞭的Dva數據流向

數據的改變發生一般是經過用戶交互行爲或者瀏覽器行爲(如路由跳轉等)觸發的,當此類行爲會改變數據的時候能夠經過 dispatch 發起一個 action,若是是同步行爲會直接經過 Reducers 改變 State ,若是是異步行爲(反作用)會先觸發 Effects 而後流向 Reducers 最終改變 State

圖片描述

3.Dva Router控制

dva 實例提供了 router 方法來控制路由,使用的是react-router
const app = dva();
import { Router, Route } from 'dva/router';
app.router(({history}) =>
  <Router history={history}>
    <Route path="/" component={HomePage} />
  </Router>
);

4.dva 應用的最簡結構(帶 model)

dva 提供多個 effect 函數內部的處理函數,比較經常使用的是 call 和 put。
call:執行異步函數
put:發出一個 Action,相似於 dispatch

課堂實戰react

// 建立應用
const app = dva();

// 註冊 Model
app.model({
  namespace: 'count',
  state: 0,
  reducers: {
    add(state) { return state + 1 },
  },
  effects: {
    *addAfter1Second(action, { call, put }) {
      yield call(delay, 1000);//異步操做
      yield put({ type: 'add' });//相似於dispatch發action
    },
  },
});

// 註冊視圖
app.router(() => <ConnectedApp />);

// 啓動應用
app.start('#root');

圖片描述

5.AntDesignPro1.0項目中的Dva

1.index.jsredux

const app = dva({
  history: createHistory(),//history能夠用來跳轉路由內含location屬性,這裏修改history默認接口,其餘接口不變----初始化
});

// 2. Plugins
app.use(createLoading());//加載插件這裏應該加載的是加載動畫插件

// 3. Register global model
app.model(require('./models/global').default);//將src/modles裏面的東西灌進去,經過namespace取

// 4. Router
app.router(require('./router').default);//全局掛載路由信息

// 5. Start
app.start('#root');

export default app._store;

2.router.js瀏覽器

export const getRouterData = app => {
    const routerConfig = {
        '/': {
            component: dynamicWrapper(app, ['user', 'login'], () => import('../layouts/BasicLayout')),
        },
        '/person/personbasetwo': {//添加路徑指向引入的組件,這條數據會被getRoutes函數渲染成真正的<Route>包裹的路由
          component: dynamicWrapper(app, ['personbaseTwo'], () => import('../routes/Person/PersonBaseTwo')),
        },
        '/person/baseInfo/:id': {//dynamicWrapper函數會吧[]裏面數據放到app的model屬性裏,app是dva的實例
          component: dynamicWrapper(app, ['personbase'], () => import('../routes/Person/PersonBase/BaseInfo')),
        },
        ·······

3.connect鏈接modelreact-router

/*dva的實例app中應該導入了全部的model,好像是在router中導入的,
這裏用解構賦值從model中取值,爲組件導入props,loading爲dva提供的動畫插件*/
@connect(({ personbaseTwo, loading }) => ({
  personbaseTwo,
  searchLoading: loading.effects['personbaseTwo/getList'],
//loding被這個異步函數影響,異步操做中就爲ture,結束就爲false
  loading: loading.effects['personbaseTwo/listpage'],
}))//從model中取數據生成本身想要的對象結構經過@修飾器放到下面組件中去
class personbaseTwo extends Component {
  constructor(props){
    super(props);
    this.state = {
    }
  }
  componentWillMount(){//組件將要渲染時拿到默認的一頁多少條和當前頁這些數據
    const { personbaseTwo:{pagination} }= this.props;
    const { page,pageSize } = pagination;
    this.props.dispatch({//轉到namespace爲personbaseTwo下面的listpage方法拿到頁碼爲page的數據
      type:'personbaseTwo/listpage',//接口根據page只去此頁數據
      payload:{
        page,
        pageSize,
      },
    });
  }
·······

4.跳轉路由架構

onOk() {//點擊肯定執行的函數
          const {id}= record;
          than.props.dispatch(routerRedux.push({//用來跳轉路由的
            pathname: `/person/baseInfoTwo/${id}`,//用這個pathname從新渲染路由頁面並傳ID
          }))
        },
相關文章
相關標籤/搜索