本文已参与「新人创作礼」活动,一起开启掘金创作之路。
前言
自 React 16.8 更新之后,函数式组件已逐步取代类组件的地位,所以在这里介绍一个高质量可靠的 React Hooks 库:ahooks
官方的介绍:ahooks,发音 [eɪ hʊks],是一套高质量可靠的 React Hooks 库。在当前 React 项目研发过程中,一套好用的 React Hooks 库是必不可少的,希望 ahooks 能成为您的选择。
就在前不久 ahooks 有 V2 升级到了 v3,有感兴趣的朋友可以看看:ahoos官网
本菜鸟也整体将 ahooks 看了下,感觉有种 食之无味,弃之可惜的感觉,当然这里面有些 Hook 还是 非常nice 的,有句话说得好:你可以不会,但你不能不知道,万一哪天用到了呢
所以学习 ahooks 是非常有必要的,请卷起来!
为了方便介绍好的 Hook,我们使用 ⭐️ 做个标记
⭐️:一般; ⭐️⭐️:重要; ⭐️⭐️⭐️:很重要;
具体演示示例: Domesy/ahook
生命周期
本文主要介绍:useMount、 useUnmount、useUpdateEffect、 useUpdate、useTrackedEffect、 useThrottleEffect、useDebounceEffect 七个Api
在React 16.8之前,类组件和函数组件的区别就是有无状态,那么在函数式出来后,有没有使 Hook 也具有相同的钩子呢?
其实 ahooks 就能解决这个问题。接下看看 ahooks 是如何使用的。如果对类组件生命周期感兴趣的同学可以看看:请你说下React的生命周期(16.0和16.4)?(面试还是会问到的(● ̄(エ) ̄●))
useMount(装载)和 useUnmount(卸载)
推荐指数:⭐️
useMount :组件装载的时候调用,类似于 class 组件的 componentDidMount useUnmount :组件卸载的时候调用,类似于 class 组件的 componentWillUnmount
示例代码:
import React from 'react';
import { Button, message } from 'antd';
import { useToggle, useMount, useUnmount } from 'ahooks';
const Test = () => {
useMount(() => {
message.info('装载');
});
useUnmount(() => {
message.info('卸载');
});
return <div>初始页面</div>;
};
const Mock: React.FC<any> = () => {
const [state, { toggle }] = useToggle(false);
return (
<>
<button type="button" onClick={() => toggle()}>
{state ? '卸载' : '装载'}
</button>
{state && <Test />}
</>
);
};
export default Mock;
useUpdateEffect 更新
推荐指数:⭐️⭐️
useUpdateEffect:在使用的时候与 useEffect 一致,不同时是 忽略了首次渲染
代码示例
import React, { useState, useEffect } from 'react';
import { Button, message } from 'antd';
import { useUpdateEffect } from 'ahooks';
const Mock: React.FC<any> = () => {
const [count, setCount] = useState(0);
const [effectCount, setEffectCount] = useState(0);
const [updateEffectCount, setUpdateEffectCount] = useState(0);
useEffect(() => {
setEffectCount((c) => c + 1);
}, [count]);
useUpdateEffect(() => {
setUpdateEffectCount((c) => c + 1);
}, [count]);
return (
<>
<p>使用Effect: {effectCount}</p>
<p>使用updateEffectCount: {updateEffectCount}</p>
<Button type='primary' onClick={() => setCount((c) => c + 1)}>
渲染
</Button>
</>
);
};
export default Mock;
useUpdate 强制更新
推荐指数:⭐️
useUpdate: 会返回一个函数,调用该函数会强制组件重新渲染(慎用~)
import React from 'react';
import { Button } from 'antd';
import { useUpdate } from 'ahooks';
const Mock: React.FC<any> = () => {
const update = useUpdate();
return (
<>
<p>时间: {Date.now()}</p>
<Button type='primary' onClick={() => update()}>
强制更新
</Button>
</
};
export default Mock;
useTrackedEffect 依赖改变
推荐指数:⭐️⭐️⭐️
useTrackedEffect:用于追踪那个依赖变化触发了 useEffect的执行
这个钩子还是非常重要的,当做一个比较复杂的功能时,我们所依赖的参数较多,我们可能需要做某一项依赖改变的时候才进行触发,这个钩子就能解决我们问题
先介绍下参数:
- changes:第几个依赖项发生了改变
- previousDeps:依赖项当前的值
- currentDeps:依赖项改变后的值
代码示例
import React, { useState } from 'react';
import { Button } from 'antd';
import { useTrackedEffect } from 'ahooks';
const Mock: React.FC<any> = () => {
const [dep1, setDep1] = useState(0);
const [dep2, setDep2] = useState(0);
const [dep3, setDep3] = useState(0);
const [depActiveList, setDepActiveList] = useState([false, false, false]);
const [text, setText] = useState('第几个依赖项改变:')
const [text1, setText1] = useState('当前的值:')
const [text2, setText2] = useState('改变后的值:')
const toggleDep = (index:number) => {
const res = [...depActiveList];
res[index] = !res[index]
setDepActiveList(res)
}
useTrackedEffect((changes, previousDeps, currentDeps)=>{
setText('第几个依赖项改变:: ' + changes);
setText1('当前的值:: ' + previousDeps);
setText2('改变后的值:: ' + currentDeps);
},[dep1, dep2, dep3])
return (
<>
<p><input type="checkbox" checked={depActiveList[0]} onChange={() => toggleDep(0)} />
第一个值 : {dep1}</p>
<p>
<input type="checkbox" checked={depActiveList[1]} onChange={() => toggleDep(1)} />
第二个值 : {dep2}
</p>
<p>
<input type="checkbox" checked={depActiveList[2]} onChange={() => toggleDep(2)} />
第三个值 : {dep3}
</p>
<Button type='primary' onClick={() => {
setText('')
setText1('')
setText2('')
depActiveList[0] && setDep1((c) => c + 1);
depActiveList[1] && setDep2((c) => c + 1);
depActiveList[2] && setDep3((c) => c + 1);
}}>
加 1
</Button>
<p>{text}</p>
<p>{text1}</p>
<p>{text2}</p>
</>
);
};
export default Mock;
useDebounceEffect:增强 effect 的防抖能力
推荐指数:⭐️
代码示例:
import React, { useState } from 'react';
import { useDebounceEffect } from 'ahooks';
const Mock: React.FC<any> = () => {
const [value, setValue] = useState<string>('hello');
const [records, setRecords] = useState<string[]>([]);
useDebounceEffect( () => {
setRecords((val) => [...val, value]);
},
[value],
{
wait: 1000,
},
);
return (
<>
<input
value={value}
onChange={(e) => setValue(e.target.value)}
placeholder="Typed value"
style={{ width: 280 }}
/>
<p style={{ marginTop: 16 }}>
<ul>
{records.map((record, index) => (
<li key={index}>{record}</li>
))}
</ul>
</p>
</>
);
};
export default Mock;
useThrottleEffect: 增强 effect 的节流能力
推荐指数:⭐️
import React, { useState } from 'react';
import { useThrottleEffect } from 'ahooks';
const Mock: React.FC<any> = () => {
const [value, setValue] = useState<string>('hello');
const [records, setRecords] = useState<string[]>([]);
useThrottleEffect( () => {
setRecords((val) => [...val, value]);
},
[value],
{
wait: 1000,
},
);
return (
<>
<input
value={value}
onChange={(e) => setValue(e.target.value)}
placeholder="Typed value"
style={{ width: 280 }}
/>
<p style={{ marginTop: 16 }}>
<ul>
{records.map((record, index) => (
<li key={index}>{record}</li>
))}
</ul>
</p>
</>
);
};
export default Mock;
End
希望跟我一样的小菜鸟亲自动手试试,加深记忆,了解就好~
其他文章