前言
ahooks常用的一些功能如下所示
useRequest
useRequest 这是早期ahooks拿手绝活,很多人都是因为这个功能才用它的,算是早期比较常用额一个功能柜了,其支持请求缓存、轮询等操作,支持控制状态,非常棒不错的功能,只不过react-hooks更新由于其他功能相对基类,再加上swr也是跟其相似,因此很多人直接改用swr不用他了 当然我不是说其不行了,而是useRequest和swr都不行,哈哈,为啥,因为其最大的特点就是缓存状态控制,实际上缓存这东西,一般前端很少直接这么用,尤其是大公司前端缓存更不能这么直接用(很多项目web端压根就不适用),都是有着自己的策略,一般只有移动端用的偏多一些罢了,新项目简单粗暴倒是好使
js
import { useRequest } from 'ahooks';
// 模拟接口
const fetchUserInfo = async () => {
const res = await fetch('/api/user');
return res.json();
};
export default function Demo() {
const { data, loading, error, refresh } = useRequest(fetchUserInfo, {
onSuccess: (res) => {
console.log('请求成功', res);
},
onError: (err) => {
console.error('请求失败', err);
}
});
if (loading) return <div>加载中...</div>;
if (error) return <div>出错了 {error.message} <button onClick={refresh}>重试</button></div>;
return (
<div>
<p>用户名:{data?.name}</p>
<button onClick={refresh}>刷新</button>
</div>
);
}
useLatest
useLatest 使用ref的方式获取新的值,主要用于解决闭包陷阱,对于一些函数页面重新渲染,但其不更新不到的(例如:useEffect中声明的闭包场景),甚至还有一些不规范的开发场景等,这个useLatest绝对是新手的一个解决方案,当然老手一般用不到它,基本上没啥棘手的场景
js
import { useState, useEffect } from 'react';
import { useLatest } from 'ahooks';
export default function UseLatestTimer() {
const [count, setCount] = useState(0);
const latestCount = useLatest(count); // 保存最新count
useEffect(() => {
const timer = setInterval(() => {
console.log(latestCount.current); // ✅ 拿到最新值
setCount(latestCount.current + 1);
}, 1000);
return () => clearInterval(timer);
}, []); // 依然空依赖,不用加count
return (
<div>
count: {count}
</div>
);
}
useSetState
这个也算是一个过时的东西了,早期react18之前,基本上异步场景,setState每次执行都会触发一次渲染,非常浪费性能,对于一些场景需要同时更新多个状态的时候,其能够大幅度减少渲染次数从而减少效率,当然不是说用不到了,现在仍然很多公司留存老项目根本没办法更新react版本,会出大问题,因此useStateState能很好的发挥作用
js
import { useSetState } from 'ahooks';
export default function UseSetStateDemo() {
const [state, setState] = useSetState({
name: '小明',
age: 18,
visible: false,
});
return (
<div>
<p>name:{state.name} age:{state.age}</p>
<button onClick={() => setState({ age: state.age + 1 })}>年龄+1</button>
{/* 只更新部分字段,其余保留,不需要 ...state */}
<button onClick={() => setState({ visible: true, name: '小红' })}>修改name+弹窗</button>
{/* 函数式更新 */}
<button onClick={() => setState(prev => ({ age: prev.age + 2 }))}>年龄+2(函数式)</button>
{/* 重置回初始值 */}
<button onClick={() => setState({})}>重置</button>
</div>
);
}
useDebounce、useThrottle
useDebounce、useThrottle 常见的防抖接口函数,对于搜索、创建接口非常的常见(如果你没用,我是测试要给你提bug了哈),能随时更新内容规避新手闭包的函数体,固定的操作函数,不得不说考虑的太周到了,让你爱不释手
js
import { useState } from 'react';
import { useDebounce } from 'ahooks';
export default function UseDebounceDemo() {
const [inputVal, setInputVal] = useState('');
// 防抖值:inputVal变化后延迟500ms才更新 debouncedVal
const debouncedVal = useDebounce(inputVal, { wait: 500 });
return (
<div>
<input
value={inputVal}
onChange={(e) => setInputVal(e.target.value)}
placeholder="输入搜索词"
/>
<p>原始值:{inputVal}</p>
<p>防抖后值:{debouncedVal}</p>
</div>
);
}
js
import { useState } from 'react';
import { useThrottle } from 'ahooks';
export default function UseThrottleDemo() {
const [scrollTop, setScrollTop] = useState(0);
// 节流值:每300ms最多更新一次
const throttledScrollTop = useThrottle(scrollTop, { wait: 300 });
const onScroll = (e: React.UIEvent<HTMLDivElement>) => {
setScrollTop(e.currentTarget.scrollTop);
};
return (
<div style={{ height: 200, overflow: 'auto' }} onScroll={onScroll}>
<div style={{ height: 1000 }}>
<p>实时scrollTop: {scrollTop}</p>
<p>节流后scrollTop: {throttledScrollTop}</p>
</div>
</div>
);
}
useInterval、useTimeout
useInterval、useTimeout 这两个也算是相对基类的功能了,一般开发者很少使用,不过其确实能够减少一些无脑操作,还加上了一些暂停继续等状态例如:不用手动释放计时器了(很多开发者都会忘记在页面结束的时候释放计时器),还加上了一些暂停继续等状态,当然其也引出了一些新语法,属于老手看着用,新手最好用的处境
js
import { useState } from 'react';
import { useInterval } from 'ahooks';
export default function UseIntervalDemo() {
const [count, setCount] = useState(0);
const [delay, setDelay] = useState(1000);
// 自动启动
const { pause, resume, isRunning } = useInterval(() => {
setCount((c) => c + 1);
}, delay);
return (
<div>
<p>count: {count}</p>
<p>定时器状态:{isRunning ? '运行中' : '已暂停'}</p>
<button onClick={pause}>暂停</button>
<button onClick={resume}>继续</button>
<button onClick={() => setDelay(500)}>改为500ms</button>
</div>
);
}
js
import { useState } from 'react';
import { useTimeout } from 'ahooks';
export default function UseTimeoutDemo() {
const [show, setShow] = useState(false);
// 3秒后执行回调,返回控制器
const { start, cancel, isActive } = useTimeout(() => {
setShow(true);
}, 3000);
return (
<div>
<p>{show ? '3秒倒计时结束' : '等待触发'}</p>
<button onClick={start}>开始倒计时</button>
<button onClick={cancel}>取消倒计时</button>
<p>定时器激活:{isActive ? '是' : '否'}</p>
</div>
);
}