使用前了解
dva的作用和redux的作用一样,在umi的项目中都是使用dva来管理状态的,,dva也是基于react-redux和reudx基础上做了进一步封装的,然后语法有点像vuex,因此会react-redux和vuex的小伙伴学起来很快。
核心概念model
首先先带你了解dva中的核心,model的使用,作用是reducer和action的结合。dva官网可能有些地方没说明清除,我这里讲解的比较详细,看完下面代码,你对dva的model也算是基本掌握了。

export default{
  namespace: 'list',
  state: [],    // model管理的全局状态
  reducers: {   // 唯一可以修改 state 的地方,触发时机是dispatch
    add(state, { payload}) {
      return [...state,payload]   //返回值为更新的状态
    },
  },
  effects: {  // 用于处理异步操作和业务逻辑,触发时机是dispatch
   // *相当于async,yield相当于await
    *save({ payload: todo }, { put,call,select}) {
      // select 的参数是一个函数,函数接收的参数是所有model的状态,该条语句的接收值是函数的返回值
      const  mystate= yield select(store=>store.todo)
      //  getListReq需要返回promise,options是getListReq的入参
      const res= yield call(getListReq,options);   
      // put和dispatch一样
      yield put({ type: 'add', payload: res.list });
    },
  },
  subscriptions: {    // 该选项中的函数自定义命名?函数的触发时机是初始时,主要用来初始化模块状态或者做一些准备性工作
    // 注意:subscription 需要返回 unlisten 方法,用于取消数据订阅。
    setup({ history, dispatch }) {
 //初始化模块状态   
 dispatch({type:'initList',payload:Json.parse(localStorage.getItem('umi_list'))})
      // 监听 history 变化,当进入 `/` 时触发 `load` action
      return history.listen(({ pathname }) => {  // history.listen监听方法返回 unlisten
        if (pathname === '/') {
          dispatch({ type: 'load' });
        }
      });
    },
  },
}

在umi中使用dva
umi项目中已经帮我们注册好了插件plugin-dva,对dva进行了一个整合,因此在umi项目中,我们使用dva是很方便的。
在umi项目中符合以下规则的文件会被认为是 model 文件。

  • src/models 下的文件
  • src/pages 下,子目录中 models 目录下的文件
  • src/pages 下,子目录中的 model.js | model.ts

在这里插入图片描述
像这个list.js文件就是一个model。

umi里面有很多hook,我们可以不需要connect组件,直接使用hook去使用model状态即可,使用方法如下。

import {useDispatch,getDvaApp,useSelector,useStore} from "umi" 

export default () => {
  
 const dispatch=useDispatch()       // 获取dispatch
 const storeState=useSelector(s=>s)   // 获取所有model的状态
//  const dva=getDvaApp()             // 获取dva实例
//  const store=useStore()        // 获取store对象

const add=(user)=>{
  // dispatch({type:'list/add',payload:{name:'a',age:18}})
   dispatch({type:'list/add',payload:user})
}

return (
    <div>
      <button onClick={add}>add</button>
      <ul>
	    {
	      // model的文件名或者namespce值为总状态的key
	      storeState.list.map((v)=><li></li>)
	    }
      </ul>
    </div>
  );
}

也可以使用connect的方式来使用model的状态,看个人喜好吧。

import {connect} from "umi" 

const page=(props) => {
  
 const add=()=>{
  // props.dispatch({type:'list/add',payload:{name:'a'}})
  props.dispatch({type:'list/add',payload:user})
}

return (
  <div>
      <button onClick={add}>add</button>
      <ul>
	    {
	      // model的文件名或者namespce值为总状态的key
	      props.list.map((v)=><li></li>)
	    }
      </ul>
    </div>
  );
}

export default connect(s=>s)(page)
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐