alibaba 开源的 ahooks 钩子
ahooks 是怎么解决 React 的闭包问题的
react 函数式组件闭包导致的问题:
useRef => useLatest
在点击 click me 按钮后 count 无论如何更新,useEffect 回调内 count 获取的始终是 0
1 | function Counter() { |
利用 react 自带的 useRef 解决
1 | function Counter() { |
ahooks 封装的钩子 useLatest
1 | const refCount= useRef(0) |
useEvent => useMemoizedFn
回掉函数需要缓存,但是 data 形成了闭包
如果把 data 作为依赖项,又会造成缓存失效
1
2
3
4const [data, setData] = useState(0)
const callBack = useCallback(()=>{
console.log(data)
}, [])
利用 react 自带的 useRef 保持状态数据为最新
如果useCallback 回调函数里有许多状态数据需要引用,要写好多无用的代码
1
2
3
4
5
6
7
8const [data, setData] = useState(0)
const refData=useRef(data)
refData.current=data
const callBack = useCallback(()=>{
console.log(refData.current)
}, [])
利用 react 自带的 useRef 保持函数为最新,不需要考虑状态数据的问题
1
2
3
4
5
6
7
8
9const [data, setData] = useState(0)
const fun=()=>{
console.log(data)
}
const refData=useRef(fun)
refData.current=fun
const callBack = useCallback(()=>{
refData.current()
}, [])
react 一个新的提案,引入 useEffect 钩子
此函数专门为解决 useCallback 的闭包问题
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15function useEvent(handler) {
const handlerRef = useRef(null);
// 在组件render 后更新`handlerRef.current`指向
// 这样可以确保 handler 内获取的状态数据都是最新的
useLayoutEffect(() => {
handlerRef.current = handler;
});
// 用useCallback包裹,使得render时返回的函数引用一致
return useCallback((...args) => {
const fn = handlerRef.current;
return fn(...args);
}, []);
}
ahooks 的 useMemoizedFn
1 | function useMemoizedFn<T extends noop>(fn: T) { |
react-use
useRequest 网络请求 hooks
网络请求一直是前端应用最为核心的部分之一。从 jQuery 对 ajax 的封装开始到axios,请求库这几年已经得到了快速的发展。
尤其是随着 hooks 的出现,请求库终于进入了一个新的时代。
在传统的请求模型里,一个请求的完整流程是这样的:
- 用户点击,触发请求流程
- 设置相关视图的状态为 loading
- 发起请求
- 处理响应结果,关闭视图的 loading 状态
最热门的 useRequest、swr 和 react-query 三个请求 hooks
useRequest 参考 SWR 的功能 和 Antd 有更好的配合,react-query 细节控制更好
个人更倾向于 react-query,因为 starts 高,细节做的好