ahook中常用的一些hooks
官方文档:https://ahooks.js.org/zh-CN/
以下总结一些个人认为非常实用的hook:
持续更新中:
1. useRequest 请求
import {useRequest } from 'ahooks'; const getSome = async () => {}; const { data, loading, run } = useRequest(getSome, { debounceInterval: 500, manual: true, refreshDeps: [], // manual为false,可以按被动式触发 }); <div> 提交结果:{JSON.stringify(data)} </div> <Button loading={loading} onClick={run}> 提交 </Button>
2.useDynamicList 动态表单
import { useDynamicList } from 'ahooks'; const { list, remove, getKey, push } = useDynamicList(['David', 'Jack']); const { getFieldDecorator, validateFields } = props.form; <Form> { list.map((item, index) => { <Form.Item key={getKey(index)}> {getFieldDecorator(`names[${getKey(index)}]`, { initialValue: item, rules: [{ required: true }], })(<Input />)} {list.length > 1 && <Icon type="minus-circle-o" onClick={() => remove(index)} />} <Icon type="plus-circle-o" onClick={() => push('')} /> </Form.Item> }) } </Form> <Button onClick={() => { const res = props.form.getFieldsValue().names; console.log((res || []).filter(item => item)) }}> 提交 </Button>
3.useVirtualList 虚拟滚动
import { useVirtualList } from 'ahooks'; const { list, containerProps, wrapperProps } = useVirtualList(Array.from(Array(99999).keys()), { overscan: 30, // 视区上、下额外展示的 dom 节点数量 itemHeight: 60, // 行高度,静态高度可以直接写入像素值,动态高度可传入函数 }); <div {...containerProps}> <div {...wrapperProps}> { list.map(item => <div key={item.index}>{item.data}</div>) } </div> </div>
4.useDebounceFn 防抖
import { useDebounceFn } from 'ahooks'; const { run } = useDebounceFn( () => console.log('test'), { wait: 500 }, ); <div> <Button onClick={run}> Click fast! </Button> </div>
5.useThrottleFn 节流
import { useThrottleFn } from 'ahooks'; const { run } = useThrottleFn( () => console.log('test'), { wait: 500 }, ); <div> <Button onClick={run}> Click fast! </Button> </div>
6.useInterval 定时器
import { useInterval } from 'ahooks'; const [count, setCount] = useState(0); useInterval(() => { setCount(count + 1); }, 1000); <div>count: {count}</div>;
7.useUrlState state 往 url query 带上
import useUrlState from '@ahooksjs/use-url-state'; const [state, setState] = useUrlState( { page: '1', pageSize: '10' }, ); <button onClick={() => { setState((s) => ({ page: Number(s.page) + 1 })); }} > 翻页 </button>
8.useCookieState state 存放到 cookie,下次回来还能
import { useCookieState } from 'ahooks'; const [message, setMessage] = useCookieState('cookie-key'); <input value={message} onChange={(e) => setMessage(e.target.value)} />
9.useLocalStorageState state 存放到 localStorage
import { useLocalStorageState } from 'ahooks'; const [message, setMessage] = useLocalStorageState('store-key', 'default value'); <input value={message || ''} onChange={(e) => setMessage(e.target.value)} />
10.在function comp上使用和class comp一样的setState语法
import { useSetState } from 'ahooks'; const [state, setState] = useSetState<State>({ hello: '', count: 0, }); <Button onClick={() => setState({ hello: 'world' })}> 只改变state.hello,不影响state.count </Button>
11.useWhyDidYouUpdate 调试判断什么参数导致组件update
import { useWhyDidYouUpdate } from 'ahooks'; const [randomNum, setRandomNum] = useState(Math.random()); // 当组件更新时,会在console打印出来哪个发生变动,导致组件update useWhyDidYouUpdate('useWhyDidYouUpdateComponent', { ...props, randomNum });
12. 判断页面是否在可见状态
import { useDocumentVisibility } from 'ahooks'; const documentVisibility = useDocumentVisibility(); useEffect(() => { if (documentVisibility === 'visible') { console.log('当前页面在可见状态'); } else { console.log('当前页面不在可见状态'); } }, [documentVisibility]);
13.判断dom是否在可视区
import { useInViewport } from 'ahooks'; const ref = useRef(); const inViewPort = useInViewport(ref); <div ref={ref}> {inViewPort ? 'div在可视区' : 'div不在可视区'} </div>
14.js响应式窗口宽度判断
import { configResponsive, useResponsive } from 'ahooks'; configResponsive({ small: 0, middle: 800, large: 1200, }); const responsive = useResponsive(); // responsive ---> {small: true, middle: true, large: false}
15.判断dom宽高变化
import { useSize } from 'ahooks'; const ref = useRef(); const size = useSize(ref); <div ref={ref}> try to resize the preview window <br /> dimensions -- width: {size.width} px, height: {size.height} px </div>
16.获取选中的文案
import { useTextSelection } from 'ahooks'; const ref = useRef(); const selection = useTextSelection(ref); <div ref={ref}> <p>Please swipe your mouse to select any text on this paragraph.</p> </div>
17.代替useMemo、useRef的钩子
因为useMemo不能保证一定不会被重新计算
useRef如果针对复杂对象,每次渲染都创建一次会很耗性能
import { useCreation } from 'ahooks';
const foo = useCreation(() => {number: Math.random()}, []);
18.事件订阅
import { useEventEmitter } from 'ahooks'; // 事件队列 const focus$ = useEventEmitter<number>(); // 发送 focus$.emit(123); // 订阅 focus$.useSubscription(value => { console.log(value); });
19.锁定异步函数
import { useLockFn } from 'ahooks'; const submit = useLockFn(async () => { await requestSome(); }); <button onClick={submit}>Submit</button>
20.响应式修改state
import { useReactive } from 'ahooks'; const state = useReactive({ count: 0, inputVal: '', obj: { value: '', }, }); <p> state.count:{state.count}</p> <button onClick={() => state.count++}> state.count++ </button>
21.useSafeState,使用安全状态挂钩以防止在未安装的组件上设置状态,以防止在未安装的组件上设置状态时发生的内存泄漏
import { useSafeState} from 'ahooks'; const [state,setState] = useSafeState(0); <p> state.count:{state.count}</p> <button onClick={() => setState(state=>state++)}> state </button>