dva的hooks使用方法

在项目中接入dva

1. 创建一个models文件夹,并在内创建一个ts文件models/dep.ts

export default {
  namespace: 'dep',
  state: {
    depList: [],
  },
  effects: {
    *getDep({payload}, {put, call}) {
      const data = yield call(setTimeout);
      yield put({
        type: 'updateState',
        payload: {depList: data},
      });
    },
  },
  reducers: {
    updateState(state, {payload}) {
      return {...state, ...payload};
    },
  },
};

2. 在models内创建index.ts文件models/index.ts将所有的model导出

import dep from './dep';
import dep1 from './dep1';

export default [dep, dep1];

3. 创建一个dva配置文件 dva.ts,初始化dva配置

import {create} from 'dva-core';
import immer from 'dva-immer';

let app: any;

const createApp = (opt: any) => {
  app = create(opt);
  app.use(immer());

  if (!(global as any).registered) {
    opt.models.forEach((model: any) => {
      app.model(model);
    });
  }

  (global as any).registered = true;

  app.start();

  const store = app._store;
  app.getStore = () => store;

  const dispatch = store.dispatch;
  app.dispatch = dispatch;

  return app;
};

export default {
  createApp,
  getDispatch() {
    return app.dispatch;
  },
};

4. 导入第2步的models,完成dva初始化

import dvaCore from './dva';
import models from '../models';

const dva = dvaCore.createApp({
  initialState: {},
  models: models,
});

const store = dva.getStore();

export default store;

5. 在app根目录包裹所有组件

import { Provider } from 'react-redux';
import store from './store';

return <Provider store={store}>
  {children}
</Provider>

符合以下规则的文件会被认为是 model 文件,

  • src/models 下的文件
  • src/pages 下,子目录中 models 目录下的文件
  • src/pages 下,所有 model.ts 文件(不区分任何字母大小写)
src
  models/a.ts
  pages
    foo/models/b.ts
    bar/model.ts

dva配置

dva: {
  immer: true,
  hmr: false,
}

skipModelValidate

  • Type: boolean
    是否跳过 model 验证。

extraModels

  • Type: string[]
    配置额外到 dva model。

immer

  • Type: boolean | object
    表示是否启用 immer 以方便修改 reducer。
    如需兼容 IE11,需配置 { immer: { enableES5: true }}

hmr

  • Type: boolean
    表示是否启用 dva model 的热更新。

lazyLoad

  • Type: boolean
    懒加载 dva models,如果项目里 models 依赖了 import from umi 导出模块,建议开启,避免循环依赖导致模块 undefined 问题。

umi常用接口

connect

绑定数据到组件。

getDvaApp

获取 dva 实例

useDispatch

hooks 的方式获取 dispatch

useSelector

hooks 的方式获取部分数据

useStore

hooks 的方式获取 store


model 用例

import type { Effect, ImmerReducer, Reducer, Subscription } from 'umi';

export interface HomeModelState {
  name: string,
  age: number,
}

export interface HomeModelType {
  namespace: 'home';
  dva: {
    immer: true,
    hmr: false,
    lazyLoad: true,
  },
  effects: {
    query: Effect;
  };
  state: HomeModelState;
  reducers: {
    // 启用 immer 之后
    save: ImmerReducer<HomeModelState>;
    // 未启用 immer
    setData: Reducer<HomeModelState>;
  };
  subscriptions: { setup: Subscription };
}

const HomeModel: HomeModelType = {
  namespace: 'home',
  state: {
    name: 'code',
    age: 19
  },
  effects: {
    *query({ payload }, { call, put }) { },
  },
  reducers: {
    save(state, action) {
      state.name = action.payload;
      // 注意,此处一定要返回新的state
      return state; 
    },
    setData(state, action) {
      return {...state, ...action.payload};
    }
  },
  subscriptions: {
    setup({ dispatch, history }) {
      return history.listen(({ pathname }) => {
        if (pathname === '/') {
          dispatch({
            type: 'query',
          });
        }
      });
    },
  },
  dva: {
    immer: true,
    hmr: false,
    lazyLoad: true,
  }
};

export default HomeModel;

page用例

通过useSelector, useDispatch的方式使用state数据

import { useSelector, useDispatch } from 'dva';

const dispatch = useDispatch();
const {name}: any = useSelector(state => state.home);
console.log(name);

useEffect(() => {
  dispatch({
     type: 'home/save',
     payload: {name: '开心就好'},
   })
}, [])
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容