react 日常小记
useEffect#
useEffect(() => {
console.log("订阅一些事件");
return () => {
console.log("执行清除操作")
}
},[]);
useEffect中的return函数执行的场景有:
- 每次重新渲染时
- 组件销毁时
- 执行清除操作时(比如:清除定时器)
useRef#
一)useRef 可以用于保存上一次的某一个值
import React, { useState, useEffect, useRef } from 'react';
export default function RefHookDemo() {
const [count, setCount] = useState(0);
const countRef = useRef(count);
useEffect(() => {
countRef.current = count;
}, [count]);
return (
<div>
<h2>前一次的值: {countRef.current}</h2>
<h2>这一次的值: {count}</h2>
<button onClick={e => setCount(count + 1)}>+1</button>
</div>
)
}
原理:
function usePrevious(value) {
const ref = useRef();
useEffect(() => {
ref.current = value;
});
return ref.current;
}
这个函数再渲染过程中总是返回上一次的值,因为 ref.current 变化不会触发组件的重新渲染,所以需要等到下次的渲染才能显示到页面上。
二)useRef 可以用于保存不需要变化的值
它可以用来保存一些在组件整个生命周期都不需要变化的值。最常见的就是定时器的清除场景。
当用全局变量设置定时器后,若组件里有state变化或者他的父组件重新render等原因导致这个组件重新render的时候,我们会发现,点击停止按钮,定时器依然会不断的在控制台打印,定时器清除事件无效了。
原因是:组件重新渲染之后,这里的timer以及clearTimer 方法都会重新创建,timer已经不是定时器的变量了
三)useRef 实现深度依赖比较
使用useEffect 只能进行浅比较,因为当传入对象时,就会无限循环,最后栈溢出,可以使用useRef比较对象
import equal from 'fast-deep-equal';
export useDeepEffect = (callback, deps) => {
const emitEffect = useRef(0);
const prevDeps = useRef(deps);
if (!equal(prevDeps.current, deps)) {
// 当深比较不相等的时候,修改emitEffect.current的值,触发下面的useEffect更新
emitEffect.current++;
}
prevDeps.current = deps;
return useEffect(callback, [emitEffect.current]);
}
总结:#
- useRef 是定义在实例基础上的,如果代码中有多个相同的组件,每个组件的 ref 只跟组件本身有关,跟其他组件的 ref 没有关系。
- 组件前定义的 global 变量,是属于全局的。如果代码中有多个相同的组件,那这个 global 变量在全局是同一个,他们会互相影响。
- 组件重新渲染之后,全局变量会被重新创建,ref 则不会被刷新。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具