What is ahooks

Ahooks was developed by the Front-end team of Ali. It is a library based on the React Hooks, which are used frequently and with high quality. The Hooks were created to eliminate the need to define class when building React components. It has been proved from the development that the class architecture used in React long ago became tedious due to the large project structure and the maintenance of class components. You often find yourself writing large, complex components that are hard to break down, are so coupled that they are hard to break down into small parts, and the code is distributed across multiple lifecycle methods, making reading, maintaining, and testing particularly tricky. In addition, we must bind the method to this to ensure that this is accessible within the component. There are too many prop drilling problems — also known as wrapper hell — when dealing with higher-order components. As a result, hooks began to emerge in react development, and ali’s development team wrapped the hooks used in react development into a complete set of hooks libraries, which gave us the name Ahooks.

The predecessor of Ahooks is the ant open source @umiJS /hooks, so it can be said that Ahooks are version 2.0 of Umi Hooks.

Study documents

  • Ahooks website
  • Ahooks Ali community
  • Umi Hooks- Help embrace React Hooks
  • Ahooks source

3. Ahooks installation

3.1 download

NPM I ahooks or YARN add ahooks

3.2 Load on demand

Hooks can be loaded on demand by writing the following.

import useToggle from 'ahooks/es/useToggle';
Copy the code

Note: Ahooks support tree shaking based on ES Module by default. For js, importing import {useToggle} from ‘ahooks’ also works on demand.

If you use Babel, you can use babel-plugin-import to load on demand. You could still write:

import { useToggle } from 'ahooks';
Copy the code

The plugin will help you convert to ahooks/es/useToggle.

Four. Basic use

4.1 Simple Case

Here is an example of a text toggle that uses the hooks function useToggle

import React from 'react'
import { useToggle } from "ahooks";

const Index = (props) = > {
    const [state, { toggle }] = useToggle();
    return (
        <>
         
                {
                    state?<p>According to</p>:<p>hidden</p>
                }
                <p>
                    <button onClick={()= >Toggle switch ()} ></button>
                </p>
        </>)}export default Index
Copy the code

Hooks

5.1 useRequest

This is the hooks that are used to send requests. Those who have used umi know that sending requests is using useRequest

It has the following features:

  • Automatic request/manual request
  • SWR(stale-while-revalidate)
  • Cache/preload
  • Screen focus rerequested
  • polling
  • Image stabilization
  • The throttle
  • Parallel requests
  • Rely on request
  • loading delay
  • paging
  • Load more, data recovery + scroll position recovery

In the following example, useRequest receives an asynchronous function getSome, which is automatically triggered when the component is first loaded. In addition, useRequest automatically manages loading, data, and error states of asynchronous requests.

import {useRequest } from 'ahooks';
const getSome = async() = > {};const { data, loading, run } = useRequest(getSome, {
debounceInterval: 500.manual: true.refreshDeps: [].// Manual is false and can be triggered passively
});
Copy the code

5.2 the cache hooks

5.2.1 useCookieState

import { useCookieState } from 'ahooks';

const [message, setMessage] = useCookieState('cookie-key');

<input
  value={message}
  onChange={(e)= > setMessage(e.target.value)}
/> 
Copy the code

5.2.2 useLocalStorageState

import { useLocalStorageState } from 'ahooks';

const [message, setMessage] = useLocalStorageState('store-key'.'default value');

<input
  value={message || ''}
  onChange={(e)= > setMessage(e.target.value)}
/>
Copy the code

5.2.3 requires useSessionStorageState

import { useSessionStorageState } from 'ahooks';

const [message, setMessage] = useSessionStorageState('store-key'.'default-value');

<input
  value={message}
  onChange={(e)= >{ setMessage(e.target.value); }} / >

Copy the code

5.3 Performance optimization hooks

5.3.1 useCreation

This hook is used instead of useMemo and useRef hooks, because useMemo does not guarantee recalculation, and useRef creates complex objects once for each rendering

import { useCreation } from 'ahooks';

const foo = useCreation(() = > {number: Math.random()}, []);
Copy the code

5.3.2 useDebounceFn

This hook is used for shaking control

import { useDebounceFn } from 'ahooks';

const { run } = useDebounceFn(
  () = > console.log('test'),
  { wait: 500});<div>
  <Button onClick={run}>
    Click fast!
  </Button>
</div>
Copy the code

5.3.3 useThrottleFn

This hook is used to throttle

import { useThrottleFn } from 'ahooks';

const { run } = useThrottleFn(
  () = > console.log('test'),
  { wait: 500});<div>
  <Button onClick={run}>
    Click fast!
  </Button>
</div>
Copy the code

5.3.4 useInterval

This hook functions as a timer

import { useInterval } from 'ahooks';

const [count, setCount] = useState(0);

useInterval(() = > {
  setCount(count + 1);
}, 1000);

<div>The Numbers: {count}</div>
Copy the code

5.3.5 useVirtualList

A Hook that provides the ability to virtualize lists to solve the problem of slow first screen rendering and scrolling lag when rendering massive data.

import { useVirtualList } from 'ahooks';

const { list, containerProps, wrapperProps } = useVirtualList(Array.from(Array(99999).keys()), {
	overscan: 30.// The number of extra DOM nodes displayed above and below the viewport
	itemHeight: 60.Static height can be written directly to the pixel value, and dynamic height can be passed into the function
});
Copy the code

5.4 Manipulating DOM hooks

5.4.1 useClickAway

This hook identifies an area that is triggered when the mouse clicks outside of the area and can do something outside of the area

import React,{useRef} from 'react'
import { useClickAway } from 'ahooks';

const Index=(props) = > {
 
const ref = useRef();
useClickAway(() = > {
  console.log('Click outside of div')
}, ref);

return(
  <div ref={ref} style={{width:'200px',height:'100px',background:'red',
  lineHeight:'100px',textAlign:'center'}} >This is a region</div>)}export default Index
Copy the code

5.4.2 useDocumentVisibility

You can get the visible state of the page and listen for the visible state of the Document

import React,{useEffect} from 'react'
import { useDocumentVisibility } from 'ahooks';

const documentVisibility = useDocumentVisibility();
useEffect(() = > {
  if (documentVisibility === 'visible') {
    console.log('Current page is visible');
  } else {
    console.log('Current page is not visible');
  }
}, [documentVisibility]);

Copy the code

5.4.3 useEventListener

This hook is similar to the addEventListener in dom operations that bind events to DOM elements

This hook can pass three arguments

parameter instructions type The default value
eventName The name of the event string
handler The processing function Function
options Settings (Optional) Options

In its source code, the element is bound this way, also using the addEventListener

    targetElement.addEventListener(eventName, eventListener, {
      capture: options.capture,
      once: options.once,
      passive: options.passive,
    });
Copy the code

use

import React, {
  useState,
  useRef
} from 'react'
import {
  useEventListener
} from 'ahooks';

const Index = (props) = > {

  const [value, setValue] = useState(0);

  const clickHandler = () = > {
    setValue(value + 1);
  };

  const ref = useRef();
  useEventListener('click', clickHandler, {
    target: ref
  });

  const style = {
    width: '100px'.height: '100px'.background: 'red'.lineHeight: '100px'.textAlign: 'center'
  }
  return ( 
    <>
    <p>This is a number: {value}</p> 
    <div ref = {ref} style = {style} >Gal.</div> 
    </>)}export default Index
Copy the code

5.4.4 useInViewport

This hook can see if the target element is visible

import { useInViewport } from 'ahooks';

const ref = useRef();
const inViewPort = useInViewport(ref);

<div ref={ref}>{inViewPort ? 'div in viewable ': 'div out of viewable '}</div>
Copy the code

In the source code, it first uses a getBoundingClientRect to observe the position of the target element and determine whether its top,bottom,left and right are in the visible area. Then, it uses IntersectionObserver to monitor if the position of the target element changes. Whether the target element is still visible

// This uses the [IntersectionObserver API], which can automatically "observe" whether elements are visible
  const observer = new IntersectionObserver((entries) = > {
      for (const entry of entries) {
        if (entry.isIntersecting) {
          setInViewport(true);
        } else {
          setInViewport(false); }}}); observer.observe(elas HTMLElement);

    return () = > {
      observer.disconnect();
    };
  }, [target]);
Copy the code

5.4.5 useResponsive

This hook listens for the size of the browser viewport and performs screen adaptation functions

import React from 'react'
import { configResponsive, useResponsive } from 'ahooks';
const Index=(props) = > {
configResponsive({
  small: 0.middle: 800.large: 1200});const responsive = useResponsive();
    return (
        <>  
      <h1>Change the viewport size of your browser</h1>
      {Object.keys(responsive).map((key) => (
        <p key={key}>
          {key} {responsive[key] ? '✔' : '✘'}
        </p>
      ))}
  
        </>)}export default Index
Copy the code

5.4.6 useEventEmitte

This hook is used to implement event subscription

import { useEventEmitter } from 'ahooks';

// Event queue
const focus$ = useEventEmitter<number>();

/ / send
focus$.emit(123);

/ / subscribe
focus$.useSubscription(value= > {
  console.log(value);
});
Copy the code