常用的React Hooks用法

1、useRequest

useRequest 是一个强大的异步数据管理的 Hooks,React 项目中的网络请求场景使用 useRequest 就够了。

useRequest 通过插件式组织代码,核心代码极其简单,并且可以很方便的扩展出更高级的功能。目前已有能力包括:

  • 自动请求/手动请求
  • 轮询
  • 防抖
  • 节流
  • 屏幕聚焦重新请求
  • 错误重试
  • loading delay
  • SWR(stale-while-revalidate)
  • 缓存

简单使用:

TypeScript 复制代码
import { useRequest } from 'ahooks';
import React from 'react';

function getUsername(): Promise<string> {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(xxx);
    }, 1000);
  });
}

export default () => {
  const { data, error, loading } = useRequest(getUsername);

  if (error) {
    return <div>failed to load</div>;
  }
  if (loading) {
    return <div>loading...</div>;
  }
  return <div>Username: {data}</div>;
};


//本段代码中,加载此页面时候会自动调用该getUserName()方法
const { data, error, loading } = useRequest(getUsername)
//此条代码含义为
  //  1、data:请求发送完成之后返回的结果
  //  2、error:请求失败,或者发生错误
  //  3、loading:请求是否完成,请求完成为flse,未完成为true

//页面加载时候带参请求
const { data } = useRequest(()=>getUsername( { aaa : xxx }))


//需要进行手动控制是否调用则需要添加一个{ manual:true } 参数,以及run/runAsync方法
const { loading, run } = useRequest(changeUsername, {
  manual: true
});
//在后续代码中通过调用run()方法,即可调用该请求,假设请求过多,则需要给方法取个别名
const { loading, run : getUsernameRun } = useRequest(changeUsername, {
  manual: true
});

//runAsync 用法与 run类似,但是异步调用,按需使用



//完整Api
const {
  loading: boolean,    //请求是否完成
  data?: TData,        //请求返回结果
  error?: Error,       //请求抛出的异常
  params: TParams || [],    //请求参数数组 例:run(1,2,3) 为 param = [1,2,3]
  run: (...params: TParams) => void,    //手动触发调用请求,异常自动处理通过onErrot()
  runAsync: (...params: TParams) => Promise<TData>,    //与run一致,返回Promise,自行处理异常
  refresh: () => void,       //使用上次的param,重新调用run方法
  refreshAsync: () => Promise<TData>,    //使用上次的param,重新调用runAsync方法
  mutate: (data?: TData | ((oldData?: TData) => (TData | undefined))) => void,//直接修改data
  cancel: () => void,    //忽略当前Promise的响应
} = useRequest<TData, TParams>(
  service: (...args: TParams) => Promise<TData>,    //请求路径
  {
    manual?: boolean,    //是否手动触发请求接口
    defaultParams?: TParams,    //首次执行时候默认传递给接口的参数
    onBefore?: (params: TParams) => void,    //请求执行前触发
    onSuccess?: (data: TData, params: TParams) => void,    //请求执行成功(resolve)之后触发
    onError?: (e: Error, params: TParams) => void,    //请求失败reject触发
    onFinally?: (params: TParams, data?: TData, e?: Error) => void,    //请求执行完成之后触发
  }
);

2、useState

用法与class的this.setState基本一致

TypeScript 复制代码
//使用案例
 const [state, setState] = useSetState<State>({
    hello: '',
    count: 0,
  });

//取值
{ state }

//设置值,设置hello
{ setState({ hello : 'haha' }) }  //此时state中的hello值为 haha

//因为useState为异步的,有时候使用会需要第一时间更新数据,这个时候可以采用一个中间值来转换使用
const tempParam = { ...state, keywords: params?.orderKeyWord }
//此时可以使用temParam作为参数来使用,再使用setState重新赋值即可
setState(tempParam)

//整体Api
const [state, setState] = useSetState<T extends Record<string, any>>(
  initialState: T = {} as T
): [T, (patch: Partial<T> | ((prevState: T) => Partial<T>)) => void]

3、useEffect *

useEffect用于处理组件中的副作用,用来取代生命周期函数

用法:在react中,可以在生命周期中执行副作用操作,在react hooks中,可以在useEffect中执行副作用操作。

执行时机,可以看作

1、componentDidMount

2、componentDidUpdate

3、componentWillUnmount

这三个生命周期函数组合,即在这三个时候都会执行一次

参数用法(无需清除的副作用操作:直接在useEffect( method )中传入操作函数method即可)

useEffect()有两个参数:

1、是要执行的参数;

2、依赖项数组(根据需求判断是否需要填写),判断数组里的变量是否发生变化来决定是否执行函数

TypeScript 复制代码
useEffect (要执行的参数,依赖数组)

只写第一个参数:

TypeScript 复制代码
//1.若不写第二个参数,函数操作每次都会执行 useEffect(method)          
const [ count,setCount  ]= useState(0)
  useEffect(()=>{
      console.log('第',{count},'次')
  })    //此处并未添加第二个参数
  return (
    <div>
      <h2>点击了{count}次</h2>
      <button onClick={ () => {setCount( count + 1 )}}>click me</button>
    </div>
  );

启动输出结果:

点击按钮之后执行结果

只写第二个参数,且为空数组:

TypeScript 复制代码
//2.有第二个参数但数组为空,则副作用仅在组件挂载和卸载时执行。useEffect( ()=>{doSomeThing}, [])
  const [ count,setCount  ]= useState(0)
  useEffect(()=>{
      console.log('第',{ count : count+1 },'次')
  },[])    //此处添加了一个空数组
  return (
    <div>
      <h2>点击了{count}次</h2>
      <button onClick={ () => {setCount( count + 1 )}}>click me</button>
    </div>
  );

启动输出结果:

点击之后输出:

小结:可见假如给到第二个参数为空数组时候,useEffect()只在页面加载完成之后执行一次,而后不会再次执行

第二个参数为可变数组:

TypeScript 复制代码
//3.若有第二个参数且数组里的变量不为空,则变量有变化时执行副作用操作,无变化则不执行.
//useEffect(()=>{doSomeThing}, [a]), a 变化时执行(任意一个或全部变化)
  const [ count,setCount  ]= useState(0);
  useEffect(()=>{
      console.log('第',{ count : count+1 },'次')
  },[count]);
  return (
    <div>
      <h2>点击了{count}次</h2>
      <button onClick={ () => {setCount( count + 1 );}}>click me</button>
    </div>
  );

启动输出结果:

点击之后执行结果:

参数用法(需要清除的副作用操作:比如监听事件,useEffect( method )在method中添加了一个监听事件,取消监听只需要在method里return一个取消监听的函数即可)

不添加第二个参数

TypeScript 复制代码
//未传递第二个参数
  const [ count,setCount  ]= useState(0);
  useEffect(()=>{
      console.log('加载或者数据变化执行了')
      return ()=>{
          console.log('执行了清除函数')
          setCount(0)
      }
  });
  return (
    <div>
      <h2>点击了{count}次</h2>
      <button onClick={ () => {setCount( count + 1 );}}>click me</button>
    </div>
  );

执行结果:

点击之后执行结果:

因为useEffect中再次执行了setCount,所以导致又使用了一次useEffect,即加载了两次

添加第二个参数,且第二个参数为空数组

TypeScript 复制代码
//添加[]空数组为第二个函数,且有return时,切换组件时才会只执行清除函数
//否则只在加载页面加载一次useEffect,且不执行清除函数

添加第二个参数,且第二个数组监听数据变化

TypeScript 复制代码
//数据加载时候不执行清除函数,只执行一次useEffect
//点击事件执行时候,执行useEffect,且会执行清除函数
//切换到别的组件,也会执行一次清除副作用函数

  const [ count,setCount  ]= useState(0);
  useEffect(()=>{
      console.log('加载或者数据变化执行了')
      return ()=>{
          console.log('执行了清除函数')
          setCount(0)
      }
  },[count]);
  return (
    <div>
      <h2>点击了{count}次</h2>
      <button onClick={ () => {setCount( count + 1 );}}>click me</button>
    </div>
  );

总结:

  • return

    • 第二个参数是副效应函数的依赖项,只有该变量发生变化的时候,副效应函数才执行;
    • 第二个参数为空数组时候,只在页面加载时候执行一次。
  • 当有 return

    • 如果没有第二个参数,页面数据发生变化时候会执行,且return也会执行;
    • 如果第二个参数是一个空数组,页面加载时候执行一次useEffect,不执行其中return,在组件切换之后会执行return;
    • 如果有依赖项,依赖项发生变化的时候,先执行return,而后再执行useEffect内容。

useSelector、useDispacher待~

相关推荐
懒大王爱吃狼1 小时前
Python教程:python枚举类定义和使用
开发语言·前端·javascript·python·python基础·python编程·python书籍
小牛itbull2 小时前
ReactPress:重塑内容管理的未来
react.js·github·reactpress
待磨的钝刨2 小时前
【格式化查看JSON文件】coco的json文件内容都在一行如何按照json格式查看
开发语言·javascript·json
前端青山7 小时前
Node.js-增强 API 安全性和性能优化
开发语言·前端·javascript·性能优化·前端框架·node.js
从兄8 小时前
vue 使用docx-preview 预览替换文档内的特定变量
javascript·vue.js·ecmascript
清灵xmf9 小时前
在 Vue 中实现与优化轮询技术
前端·javascript·vue·轮询
薛一半10 小时前
PC端查看历史消息,鼠标向上滚动加载数据时页面停留在上次查看的位置
前端·javascript·vue.js
过期的H2O211 小时前
【H2O2|全栈】JS进阶知识(四)Ajax
开发语言·javascript·ajax
MarcoPage11 小时前
第十九课 Vue组件中的方法
前端·javascript·vue.js
你好龙卷风!!!11 小时前
vue3 怎么判断数据列是否包某一列名
前端·javascript·vue.js