何为useRef

useRef是随着react函数式组件发展而来的,是react众多官方hook中的一个,调用useRef可以返回一个伴随这组件整个声明周期不发生改变的对象,这个对象常见的用途有两个:

  • 用于绑定dom元素,从而实现对dom元素的操作
  • 用于保存不希望随着组件重新渲染而改变的值,如定时器

在项目中的应用

我在做自己的网站时遇到过一些场景,实现效果与预想中的不一致,让我头大了好一阵子,所幸最终都得到了解决,为了在以后能够回来看一下,同时记录学习过程中的一些知识点,现将这两个场景记录如下。

一、编写自己的防抖函数

在编写登录注册功能时,需要对用户输入的信息进行校验,包括前端的校验以及和后端通信的校验,如果只是前端的校验还好,如果在用户输入的信息每次发生变化都去和服务器通信校验的话,大量的http请求会对服务器造成压力,所以我希望对这些行为进行防抖处理。

useDebounce.ts

import { useEffect, useRef } from "react"

export const useDebounce = (f:Function,delay:number)=>{
//使用useRef保存计时器,以此确保在组件更新时始终是同一个计时器,而不是重新创建
const {current} = useRef<{timmer:any}>({timmer:null}) useEffect(()=>{
return ()=>{
//组件销毁时清除计时器
clearTimeout(current.timmer)
}
},[])
return function(...args:any[]){
//如果计时器存在,则清除该计时器
if(current.timmer){
clearTimeout(current.timmer)
}
//重新赋值计时器,并在计时结束后执行回调函数
current.timmer = setTimeout(() => {
f.apply(useDebounce,args)
}, delay);
}
}

这里我将防抖函数写成了一个自定义的hook,也是写的第一个hook,调用时需要传入两个参数,第一个参数是需要进行防抖处理的函数,第二个参数是防抖的延时时间,hook返回值是经过防抖处理的函数。

二、解决回调函数中获取不到最新state值的问题

在实现获取评论列表时,我希望每次只获取一定数量的评论,当用户浏览到页面底端时再获取新的评论,在实现过程中我用到了intersectionObserverAPI,并在它的回调函数中引用了组件中的一些state。

当我直接在useEffect副作用函数中进行绑定监听的元素时,发现回调函数中的state值一直保持observer对象创建时的值,经过查询相关资料,得知这可能是因为闭包的影响。解决办法是使用useRef创建一个对象用于保存observer对象,并在相关state值发生变化后释放原来的observer对象,创建一个新的observer对象,并重新绑定要监听的元素。

//指向要监听的元素
const bref = useRef(null)
//保存observer对象
const observer = useRef<any>() //每当comments变化,都会重新创建一个observer对象,其回调函数中引用的就是最新的state值
useEffect(() => {
let c = new IntersectionObserver((entries) => {
if (entries[0].intersectionRatio > 0) {
if (page * pageNum <= count) {
const fd = new FormData()
fd.append('articleId', param.articleid)
fd.append('page', page + 1)
fd.append('pageNum', pageNum)
http({ url: '/comment/comments', options: { method: 'POST', body: fd } }).then(res => {
if (count !== res.count) {
setcount(res.res.count)
} setpage(page + 1)
setcomments([...comments, ...res.res.rows])
})
} }
})
//取消旧的监听
if (observer.current) {
observer.current.unobserve(bref.current)
}
//保存新的observer对象,并建立新的监听
observer.current = c
observer.current.observe(bref.current)
}, [comments])



实践出真知,在项目中发现问题,寻找解决问题的方法,大江不止兮水长流,不断积累,丰富阅历,提升能力。

react中useRef的应用的更多相关文章

  1. React 中阻止事件冒泡的问题

    在正式开始前,先来看看 JS 中事件的触发与事件处理器的执行. JS 中事件的监听与处理 事件捕获与冒泡 DOM 事件会先后经历 捕获 与 冒泡 两个阶段.捕获即事件沿着 DOM 树由上往下传递,到达 ...

  2. 在React中使用 react-router-dom 编程式路由导航的正确姿势【含V5.x、V6.x】

    ## react-router-dom 编程式路由导航 (v5) ###### 1.push跳转+携带params参数 ```jsx props.history.push(`/b/child1/${i ...

  3. React中实现keepalive组件缓存效果

    背景:由于react官方并没有提供缓存组件相关的api(类似vue中的keepalive),在某些场景,会使得页面交互性变的很差,比如在有搜索条件的表格页面,点击某一条数据跳转到详情页面,再返回表格页 ...

  4. 理解React中es6方法创建组件的this

    首发于:https://mingjiezhang.github.io/(转载请说明此出处). 在JavaScript中,this对象是运行时基于函数的执行环境(也就是上下文)绑定的. 从react中的 ...

  5. 【原】React中,map出来的元素添加事件无法使用

    在使用react中,经常用到react的map函数,用法和jquery里中的map一样,但是,如果你在每个map出来的元素中添加,你会发觉添加的事件无法关联, 比如,我们很多的评论,我需要在每个评论下 ...

  6. React中props.children和React.Children的区别

    在React中,当涉及组件嵌套,在父组件中使用props.children把所有子组件显示出来.如下: function ParentComponent(props){ return ( <di ...

  7. Immutable 详解及 React 中实践

    本文转自:https://github.com/camsong/blog/issues/3 Shared mutable state is the root of all evil(共享的可变状态是万 ...

  8. React中父组件与子组件之间的数据传递和标准化的思考

    React中父组件与子组件之间的数据传递的的实现大家都可以轻易做到,但对比很多人的实现方法,总是会有或多或少的差异.在一个团队中,这种实现的差异体现了每个人各自的理解的不同,但是反过来思考,一个团队用 ...

  9. React中使用CSSTransitionGroup插件实现轮播图

    动画效果,是一个页面上必不可少的功能,学习一个新的东西,当然就要学习,如何用新的东西,用它的方法去实现以前的东西啦.今天呢,我就在这里介绍一个试用react-addons-css-transition ...

  10. 在React中使用Redux

    这是Webpack+React系列配置过程记录的第六篇.其他内容请参考: 第一篇:使用webpack.babel.react.antdesign配置单页面应用开发环境 第二篇:使用react-rout ...

随机推荐

  1. PGF 概率生成函数 Probability generating function

    Probability Mass Function 离散随机变量的分布函数PMF 目录 随机结构举例 two classical combinatorial distributions PGF Pro ...

  2. vue 和 react 的区别有哪些

    vue 和 react 有什么区别呢?下面从这 4 个角度来说一说! (1)从编程范式的角度讲 在 vue-loader.vue-template-compiler 的支持下,vue 可以采用 SFC ...

  3. 内核不中断前提下,Gaussdb(DWS)内存报错排查方法

    摘要:本文主要讲解如何在内核保证操作不能中断采取的特殊处理,理论上用户执行的sql使用的内存(dynamic_used_memory) 是不会大范围的超过max_dynamic_memory的内存的 ...

  4. GitHub+Typora实现云笔记一键上传

    git实现笔记自动上传功能 简介: 将更新内容自动上传同步git,无需手动提交,解锁一键式同步.流程大致为,创建新仓库,配置公钥和私钥,安装quicker软件,通过quicker上某脚本完成一键提交. ...

  5. FileReader之获取文本文件内容为字符串

    FileReader之获取文本文件内容为字符串 FileReader官网描述: FileReader 对象允许 Web 应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 Fil ...

  6. centos7搭建bsc全节点

    Centos7搭建bsc全链节点 服务器配置  CPU:8 Cores - 16 Threads RAM:131072 MB Storage:2x 2000GB NVMe Bandwidth:8400 ...

  7. 谷歌浏览器插件:FeHelper(WEB前端助手)

    背景 在现在的互联网时代,前端开发已经成为一个非常重要的领域.为了提高开发效率和质量,许多前端开发人员都喜欢使用一些相关工具来辅助他们的工作.而谷歌浏览器插件:WEB前端助手(FeHelper)就是其 ...

  8. 腾讯出品小程序自动化测试框架【Minium】系列(七)测试框架的设计和开发

    前言 整个框架的开发及调通是在3月27日晚上22点完成,如下: 这篇文章真的是拖了太久了,久到我居然把代码部分完成后,彻底给忘了,这记性,真的是年纪大了! 框架的设计开发 1.框架搭建设计要素 日志& ...

  9. LeeCode 二叉树问题(四)

    二叉搜索树的应用问题 二叉搜索树的定义 若左子树不空,则左子树上所有节点的值均小于根节点的值 若右子树不空,则右子树上所有节点的值均大于根节点的值 它的左右子树也均为二叉搜索树 中序遍历结果为一个升序 ...

  10. JUC(二)线程间通信

    目录 线程间通信 多线程编程步骤 一个加减实例 & 虚假唤醒问题 Lock接口实现 lock.newCondition设置等待条件 线程间定制化通信 线程间通信案例 设置标志位 线程间通信 多 ...