总结一些个人认为非常好用的hooks

52 阅读1分钟
  • usePersistFn 函数缓存

    • 替换useCallback的hooks,不需要写依赖数据,避免因为漏写依赖项导致函数的重新创建
    import { usePersistFn } from 'react'
    function App() { 
        const [count, setCount] = useState(0);
        const showCountWithPersist = usePersistFn(() => {
            console.log(count); 
         }); 
         return ( 
             <div className="App"> 
                 <button onClick={() => setCount((val) => val + 1)}>
                     触发父组件渲染
                 </button> 
                 <h2>count:{count}</h2> 
                 <ChildMemo showCount={showCountWithPersist} /> 
             </div> 
         ); 
     }
    
  • useRequest 请求

    import {useRequest } from 'ahooks';
    
    const getSome = async () => {};
    const { data, loading, run } = useRequest(getSome, {
        debounceInterval: 500,
        manual: true, // manual为false,可以被动式触发,及组件挂载触发,refreshDeps数组变化触发
        refreshDeps: [], 
    });
    
    <div>
        提交结果:{JSON.stringify(data)}
    </div>
    <Button loading={loading} onClick={run}>
       提交
    </Button>
    
  • 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>
    
  • useVirtualList 虚拟滚动

    import React, { useRef } from 'react';
    import { useVirtualList } from 'ahooks';
    import './App.css';
    
    
    const containerRef = useRef(null);
    const wrapperRef = useRef(null);
    const [list,scrollTo] = useVirtualList(Array.from(Array(99999).keys()), {
    containerTarget: containerRef,
    wrapperTarget: wrapperRef,
    itemHeight: 20,
    overscan: 5,
    });
    
    <>
      <button onClick={()=>{scrollTo(4)}}>滚动到第四个元素</button>
      <div ref={containerRef} style={{ height: '300px', overflow: 'auto', border: '1px solid' }}>
        <div ref={wrapperRef}>
          {list.map((ele) => (
            <div key={ele.index}>
              Row: {ele.data}
            </div>
          ))}
        </div>
      </div>
    </>
    
  • useDebounceFn 防抖

    import React, { useRef } from 'react';
    import { useDebounceFn } from 'ahooks';
    import './App.css';
    function App() {
      const { run } = useDebounceFn(
        (arg) => console.log('test'+arg),
        { wait: 500 },
      );
      return (
        <>
          <button onClick={() => run(999)}>
            提交
          </button>
        </>
      );
    }
    export default App;
    
  • useThrottleFn 节流、

    import { useThrottleFn } from 'ahooks';
    const { run } = useThrottleFn(
        (arg) => console.log('test'+arg),
        { wait: 500 },
    );
    
      <div>
        <Button onClick={() => run(999)}>
          Click fast!
        </Button>
      </div>
    
  • useInterval 定时器

    import { useInterval } from 'ahooks';
    const [count, setCount] = useState(0);
      useInterval(() => {
        setCount(count + 1);
      }, 1000);
    
    <div>count: {count}</div>;
    
  • useWhyDidYouUpdate 调试判断什么参数导致组件更新

    import { useWhyDidYouUpdate  } from 'ahooks';
    const [count, setCount] = useState(0);
    const [data, setData] = useState(0);
    useWhyDidYouUpdate('useWhyDidYouUpdateComponent',{count, data})
    
    <button onClick={() => setCount(count+1)}>
      按钮
    </button>
    
  • useClickAway 判断是否点击到元素外面

    import { useClickAway } from 'ahooks'
    const ref = useRef();
    useClickAway(() => {
      console.log('点击到div外部了')
    }, ref);
    
    return (
      <>
        <div ref={ref}> test </div>
      </>
    );
    
  • useDocumentVisibility 判断页面是否在可见状态

    import { useDocumentVisibility } from 'ahooks';
    const documentVisibility = useDocumentVisibility();
      useEffect(() => {
        if (documentVisibility === 'visible') {
          console.log('当前页面在可见状态');
        } else {
          console.log('当前页面不在可见状态');
        }
     }, [documentVisibility]);
    
  • useFullscreen 让dom元素全屏展示

    import React, { useRef } from 'react';
    import { useFullscreen   } from 'ahooks';
    import './App.css';
    
    const ref = useRef();
    const [isFullscreen, { enterFullscreen, exitFullscreen, toggleFullscreen }] = useFullscreen(ref);
      <>
        <div style={{width: 200,height: 200,border: 'solid 1px red',background: 'white'}} ref={ref}>
          {isFullscreen ? '全屏中' : '不在全屏中'}
          <button onClick={toggleFullscreen}>
            toggleFullscreen
          </button>
          <button onClick={enterFullscreen}>
            enterFullscreen
          </button>
          <button onClick={exitFullscreen}>
            exitFullscreen
          </button>
        </div>
      </>
    
  • useInViewport 判断dom是否在可视区

      import { useInViewport } from 'ahooks';
    
      const ref = useRef();
      const inViewPort = useInViewport(ref);
    
      <div ref={ref}>
        {inViewPort ? 'div在可视区' : 'div不在可视区'}
      </div>
    
  • useResponsive 窗口判断大小

    import React, { useRef } from 'react';
    import { useFullscreen   } from 'ahooks';
    import { configResponsive, useResponsive } from 'ahooks';
    import './App.css';
    
    configResponsive({
      small: 0,
      middle: 800,
      large: 1200,
    });
    
    const responsive = useResponsive();
    return (
      <>
        <p>Please change the width of the browser window to see the effect: </p>
        {Object.keys(responsive).map((key) => (
          <p key={key}>
            {key} {responsive[key] ? '✔' : '✘'}
          </p>
        ))}
      </>
    
  • useSize 监听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>
    
  • useTextSelection 获取许选中的文案

    import { useTextSelection } from 'ahooks';
    const { text } = useTextSelection();
    <div>
     <p>Please swipe your mouse to select any text on this paragraph.</p>
       选中文案:{text}
    </div>
    
  • useEventEmitter 事件订阅

      import { useEventEmitter } from 'ahooks';
      // 事件队列
      const focus$ = useEventEmitter<number>();
      // 发送
      focus$.emit(123);
      // 订阅
      focus$.useSubscription(value => {
        console.log(value);
      });
    
  • useLockFn 锁定异步函数, 异步函数执行完前不会重新执行

    import { useLockFn  } from 'ahooks';
    const submit = useLockFn(async (data) => {
      await new Promise(resolve => setTimeout(()=>{
        console.log('submit>>'+data);
        resolve();
      }, 2000));
    });
    <button onClick={() => submit(12345)}>submit</button>
    
  • useReactive 响应式修改数据

     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>
    

    更多ahooks请官网ahooks.js.org/查看