蚂蚁自定义hook库。

556 阅读2分钟

umi.js是蚂蚁金服一直在维护的项目,集成了antd-pro,dva,antv以及moment,classnames等常用插件。umi技术栈用的是react,说到react,就不免说说hook,而除了react官方的几个hook外,蚂蚁也自定义了许多非常实用的hook。具体看文档umiApi,以及ahook,这里推荐几个常用hook,其他不在赘述。

useModel

相信大家都习惯了用dva,但是dva的generator还有connect语法对于萌新还是很难理解,dva中的异步和同步还要分开写。但是如果用了useModel就不一样了,首先在与src同级目录model文件夹里面定义一个js文件,然后我们就可以愉快地写一样公用逻辑,包括异步请求,公用函数与变量。在model中的user.js:

import { useState, useCallback } from 'react'
export default ()=> { 
 const [user, setUser] = useState(null);

 const signin = useCallback((account, password) => {   
 // signin implementation   
 // setUser(user from signin API) 
 },[]);

 const signout = useCallback(() => {  
  // signout implementation   
 // setUser(null)  
  }, []); 

 return {   
  user, 
  signin,  
  signout  
}}

 在页面中使用model里面的数据的时候:

import { useModel } from 'umi';
export default () => { 
 const { user, signout} = useModel('user');  return <>
     hello{user}
     <button onClick={signout}>登出<button>
</>
};

 这样写起来就真的很方便了,无论是同步还是异步都可以直接从model里获取。说到异步,这里不得不说下下一个hook。

useRequest

  useRequest是一个强大的管理异步数据请求的 Hook,具体看文档蚂蚁请求库useRequest,

文档已经说得很详细,支持缓存轮询,分页,防抖和节流。这里主要说下,userRquest和useModel配合使用,用起来其实也非常简单。一个页面可能有很多组件组成,在一个页面的文件夹里面就会有很多文件,但是无论是index.js还是其他组件的js,只要使用同一个model,就能及时更新页面数据,这样也会省去很多不必要的组件传值。比如页面有三个组件组成,加载时需要同时进行三个请求,在model的govern.js:

import { useRequest } from '@umijs/hooks';

export default ()=>{
const { data:appData, loading:appLoading,run:queryApp} = useRequest(()=>
   service.gover.queryApp(),
  {
   manual:true,
   });
const { data:techData, loading:techLoading,run:queryTech } = useRequest(()=>
  service.gover.queryTech(),  {
   manual:true,
   });

const { data:archData, loading:archLoading,run:queryArch } = useRequest(()=>   service.gover.queryArch(),
  {
   manual:true,
   })

return {
 appData,
 appLoading,
 techData,
 techLoading, 
 appData,
 appLoading,
 queryApp, queryTech,
 queryArch}


}

 在页面的index.js可以一次性发起三个请求:

import React,{useEffect} from 'react';
import { useModel } from 'umi';

export default const GoverIndex=()=>{
  const { queryApp, queryTech,queryArch}=useModel('govern');  useEffect(()=>{
    queryApp(),
    queryTech(),
    queryArch()
   },[]);

return <>
    hello
   <AppIndex />
   <TechIndex />
   <ArchIndex />
</>
}

 在组件AppIndex.js里面使用model获取最新数据:

import { useModel } from 'umi';
import {Spin} from 'antd';

export default const AppIndex=()=>{

const {  appData,appLoading,}=useModel('govern');return <>
 <Spin spinning={appLoading}> {appData} </Spin>
</>
}

 我觉得相较于dva,这样就非常简单易懂了,不需要每个组件用connect语法,然后dispatch,也不能搞什么组件传值。model文件夹还是不要写太多,尽量提取一些经常用的公共逻辑。当然umi还有很多hook,比如获取权限的useAccess,获取路由信息的useHostor,拖拽的useDrop等。就不一一介绍了,阅读文档一目了然。

umi文档:umijs.org/zh-CN/plugi…

ahook文档:  ahooks.js.org/hooks/async