((resolve) => {
setTimeout(() => {
resolve();
}, 2000);
});
}
const Example = () => {
const [count, setCount] = useState(0);
const submit = useLockFn(async () => {
console.log('Start to submit');
await mockApiRequest();
setCount((val) => val + 1);
console.log('Submit finished');
});
return (
<>
Submit count: {count}
Submit
>
);
};
export default Example;`}
/>
## API
```typescript
function useLockFn(
fn: (...args: P) => Promise
): fn: (...args: P) => Promise;
```
### Result
| Property | Description | Type |
| -------- | ---------------------------- | ---------------------------------- |
| fn | The async function with lock | `(...args: any[]) => Promise` |
### Params
| Property | Description | Type | Default |
| -------- | ----------------- | ---------------------------------- | ------- |
| fn | An async function | `(...args: any[]) => Promise` | - |
# useLongPress (/docs/useLongPress)
## Overview
Listen for the long press event of the target element.
[Documentation and Examples](https://ahooks.js.org/hooks/use-longpress)
## Installation
```bash
pnpm dlx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useLongPress.json
```
```bash
npx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useLongPress.json
```
```bash
yarn shadcn@latest add https://shadcn-ahooks.vercel.app/r/useLongPress.json
```
```bash
bun shadcn@latest add https://shadcn-ahooks.vercel.app/r/useLongPress.json
```
Listen for the long press event of the target element.
## Examples
### Basic usage
((resolve) => {
setTimeout(() => {
resolve();
}, 2000);
});
}
const Example = () => {
const [counter, setCounter] = useState(0);
const ref = useRef(null);
useLongPress(() => setCounter((s) => s + 1), ref);
return (
Press me
counter: {counter}
);
};
export default Example;`}
/>
### Listen for click and long press events at the same time
((resolve) => {
setTimeout(() => {
resolve();
}, 2000);
});
}
const Example = () => {
const [pressCounter, setPressCounter] = useState(0);
const [clickCounter, setClickCounter] = useState(0);
const ref = useRef(null);
useLongPress(() => setPressCounter((s) => s + 1), ref, {
onClick: () => setClickCounter((s) => s + 1),
});
return (
Press me
pressCounter: {pressCounter}
clickCounter: {clickCounter}
);
};
export default Example;`}
/>
### Move threshold
((resolve) => {
setTimeout(() => {
resolve();
}, 2000);
});
}
const Example = () => {
const [pressCounter, setPressCounter] = useState(0);
const ref = useRef(null);
useLongPress(() => setPressCounter((s) => s + 1), ref, {
moveThreshold: { x: 30 },
});
return (
Press me
counter: {pressCounter}
);
};
export default Example;`}
/>
## API
```typescript
useLongPress(
onLongPress: (event: MouseEvent | TouchEvent) => void,
target: Target,
options: {
delay?: number;
moveThreshold?: { x?: number; y?: number };
onClick?: (event: MouseEvent | TouchEvent) => void;
onLongPressEnd?: (event: MouseEvent | TouchEvent) => void;
}
);
```
### Params
| Property | Description | Type | Default |
| ----------- | ---------------------------- | ----------------------------------------------------------- | ------- |
| onLongPress | Trigger function | `(event: MouseEvent \| TouchEvent) => void` | - |
| target | DOM node or Ref | `Element` \| `() => Element` \| `MutableRefObject` | - |
| options | Optional configuration items | `Options` | `{}` |
### Options
| Property | Description | Type | Default |
| -------------- | ----------------------------------------------------------------------------------- | ------------------------------------------- | ------- |
| delay | Long press time | `number` | `300` |
| moveThreshold | Move threshold after press. If exceeded, the long press function won't be triggered | `{ x?: number; y?: number }` | - |
| onClick | Click event | `(event: MouseEvent \| TouchEvent) => void` | - |
| onLongPressEnd | Long press end event | `(event: MouseEvent \| TouchEvent) => void` | - |
### Remark
Please refer to: [https://stackoverflow.com/a/11237968](https://stackoverflow.com/a/11237968) to disable the ability to long press to select text on the phone
# useMap (/docs/useMap)
## Overview
A hook that can manage the state of Map.
[Documentation and Examples](https://ahooks.js.org/hooks/use-map)
## Installation
```bash
pnpm dlx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useMap.json
```
```bash
npx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useMap.json
```
```bash
yarn shadcn@latest add https://shadcn-ahooks.vercel.app/r/useMap.json
```
```bash
bun shadcn@latest add https://shadcn-ahooks.vercel.app/r/useMap.json
```
A hook that can manage the state of Map.
## Examples
### Default usage
((resolve) => {
setTimeout(() => {
resolve();
}, 2000);
});
}
const Example = () => {
const [map, { set, setAll, remove, reset, get }] = useMap([
['msg', 'hello world'],
[123, 'number type'],
]);
return (
set(String(Date.now()), new Date().toJSON())}>
Add
setAll([['text', 'this is a new Map']])}
style={{ margin: '0 8px' }}
>
Set new Map
remove('msg')} disabled={!get('msg')}>
Remove 'msg'
reset()} style={{ margin: '0 8px' }}>
Reset
{JSON.stringify(Array.from(map), null, 2)}
);
};
export default Example;`}
/>
## API
```typescript
const [
map,
{
set,
setAll,
remove,
reset,
get
}
] = useMap(initialValue);
```
### Result
| Property | Description | Type |
| -------- | ---------------- | ------------------------------------ |
| map | Map object | `Map` |
| set | Add item | `(key: K, value: V) => void` |
| get | Get item | `(key: K) => V \| undefined` |
| setAll | Set a new Map | `(newMap: Iterable<[K, V]>) => void` |
| remove | Remove key | `(key: K) => void` |
| reset | Reset to default | `() => void` |
### Params
| Property | Description | Type | Default |
| ------------ | --------------------------- | ------------------ | ------- |
| initialValue | Optional, set default value | `Iterable<[K, V]>` | - |
# useMemoizedFn (/docs/useMemoizedFn)
## Overview
Hooks for persistent functions. In general, useMemoizedFn can be used instead of useCallback. See [FAQ](#faq) for special cases.
[Documentation and Examples](https://ahooks.js.org/hooks/use-memoizedfn)
## Installation
```bash
pnpm dlx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useMemoizedFn.json
```
```bash
npx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useMemoizedFn.json
```
```bash
yarn shadcn@latest add https://shadcn-ahooks.vercel.app/r/useMemoizedFn.json
```
```bash
bun shadcn@latest add https://shadcn-ahooks.vercel.app/r/useMemoizedFn.json
```
Hooks for persistent functions. In general, useMemoizedFn can be used instead of useCallback. See [FAQ](#faq) for special cases.
In some scenarios, we need to use useCallback to cache a function, but when the second parameter deps changes, the function will be regenerated, causing the function reference to change.
```js
const [state, setState] = useState('');
// When the state changes, the func reference will change
const func = useCallback(() => {
console.log(state);
}, [state]);
```
Using useMemoizedFn, you can omit the second parameter deps, and ensure that the function reference never change.
```js
const [state, setState] = useState('');
// func reference never change
const func = useMemoizedFn(() => {
console.log(state);
});
```
## Examples
### Default usage
{
const [count, setCount] = useState(0);
const callbackFn = useCallback(() => {
console.info(\`Current count is \${count}\`);
}, [count]);
const memoizedFn = useMemoizedFn(() => {
console.info(\`Current count is \${count}\`);
});
return (
<>
count: {count}
{
setCount((c) => c + 1);
}}
>
Add Count
call callbackFn
call memoizedFn
>
);
};
export default Example;`}
/>
### Performance Improvement
(({ showCount }) => {
const renderCountRef = useRef(0);
renderCountRef.current += 1;
return (
Render Count: {renderCountRef.current}
showParentCount
);
});
const Example = () => {
const [count, setCount] = useState(0);
const callbackFn = useCallback(() => {
console.info(\`Current count is \${count}\`);
}, [count]);
const memoizedFn = useMemoizedFn(() => {
console.info(\`Current count is \${count}\`);
});
return (
<>
count: {count}
{
setCount((c) => c + 1);
}}
>
Add Count
You can click the button to see the number of sub-component renderings
Component with useCallback function:
{/* use callback function, ExpensiveTree component will re-render on state change */}
Component with useMemoizedFn function:
{/* use memoized function, ExpensiveTree component will only render once */}
>
);
};
export default Example;`}
/>
## API
```typescript
const memoizedFn = useMemoizedFn(fn: T): T;
```
### Result
| Property | Description | Type |
| ---------- | ------------------------------------------------- | ------------------------- |
| memoizedFn | Function that the reference address never changes | `(...args: any[]) => any` |
### Params
| Property | Description | Type | Default |
| -------- | --------------------------------- | ------------------------- | ------- |
| fn | Function that require persistence | `(...args: any[]) => any` | - |
## FAQ
### The function returned by `useMemoizedFn` will not inherit properties from fn itself?
The function returned by `useMemoizedFn` is entirely different from the reference of the passed `fn`, and it does not inherit any properties from `fn` itself. If you want to preserve the properties of the function itself after memoization, `useMemoizedFn` currently does not fulfill that requirement. In this case, consider downgrading to using `useCallback` or `useMemo` instead.
Related issues: [2273](https://github.com/alibaba/hooks/issues/2273)
# useMount (/docs/useMount)
## Overview
A hook that executes a function after the component is mounted.
[Documentation and Examples](https://ahooks.js.org/hooks/use-mount)
## Installation
```bash
pnpm dlx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useMount.json
```
```bash
npx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useMount.json
```
```bash
yarn shadcn@latest add https://shadcn-ahooks.vercel.app/r/useMount.json
```
```bash
bun shadcn@latest add https://shadcn-ahooks.vercel.app/r/useMount.json
```
A hook that executes a function after the component is mounted.
## Examples
### Default Usage
{
useMount(() => {
console.info('mount');
return () => {
console.info('unmount');
};
});
return Hello World
;
};
const Example = () => {
const [state, { toggle }] = useBoolean(false);
return (
<>
{state ? 'unmount' : 'mount'}
{state && }
>
);
};
export default Example;`}
/>
## API
```typescript
useMount(fn: EffectCallback);
```
### Params
| Property | Description | Type | Default |
| -------- | --------------------------- | ---------------- | ------- |
| fn | The function to be executed | `EffectCallback` | - |
# useMouse (/docs/useMouse)
## Overview
Track cursor position
[Documentation and Examples](https://ahooks.js.org/hooks/use-mouse)
## Installation
```bash
pnpm dlx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useMouse.json
```
```bash
npx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useMouse.json
```
```bash
yarn shadcn@latest add https://shadcn-ahooks.vercel.app/r/useMouse.json
```
```bash
bun shadcn@latest add https://shadcn-ahooks.vercel.app/r/useMouse.json
```
Track cursor position
## Examples
### Default Usage
{
const mouse = useMouse();
return (
Client - x: {mouse.clientX}, y: {mouse.clientY}
Page - x: {mouse.pageX}, y: {mouse.pageY}
Screen - x: {mouse.screenX}, y: {mouse.screenY}
);
};
export default Example;`}
/>
### Mouse position relative to the element
{
const ref = useRef(null);
const mouse = useMouse(ref.current);
return (
<>
element
Mouse In Element - x: {mouse.elementX}, y: {mouse.elementY}
Element Position - x: {mouse.elementPosX}, y: {mouse.elementPosY}
Element Dimensions - width: {mouse.elementW}, height: {mouse.elementH}
>
);
};
export default Example;`}
/>
## API
```typescript
const state: {
screenX: number,
screenY: number,
clientX: number,
clientY: number,
pageX: number,
pageY: number,
elementX: number,
elementY: number,
elementH: number,
elementW: number,
elementPosX: number,
elementPosY: number,
} = useMouse(target?: Target);
```
### Params
| Property | Description | Type | Default |
| -------- | ------------------ | ----------------------------------------------------------- | ------- |
| target | DOM element or ref | `() => Element` \| `Element` \| `MutableRefObject` | - |
### result
| Property | Description | Type |
| ----------- | ------------------------------------------------------------------------------------------------------------------ | -------- |
| screenX | Position left relative to the top left of the physical screen/monitor | `number` |
| screenY | Position top relative to the top left of the physical screen/monitor | `number` |
| clientX | Position left relative to the upper left edge of the content area | `number` |
| clientY | Position top relative to the upper left edge of the content area | `number` |
| pageX | Position left relative to the top left of the fully rendered content area in the browser | `number` |
| pageY | Position top relative to the top left of the fully rendered content area in the browser | `number` |
| elementX | Position left relative to the upper left edge of the target element | `number` |
| elementY | Position top relative to the upper left edge of the target element | `number` |
| elementH | Target element height | `number` |
| elementW | Target element width | `number` |
| elementPosX | The position of the target element left relative to the top left of the fully rendered content area in the browser | `number` |
| elementPosY | The position of the target element top relative to the top left of the fully rendered content area in the browser | `number` |
# useMutationObserver (/docs/useMutationObserver)
## Overview
A hook that provides the ability to watch for changes being made to the DOM tree, refer to [MutationObserver](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver)
[Documentation and Examples](https://ahooks.js.org/hooks/use-mutationobserver)
## Installation
```bash
pnpm dlx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useMutationObserver.json
```
```bash
npx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useMutationObserver.json
```
```bash
yarn shadcn@latest add https://shadcn-ahooks.vercel.app/r/useMutationObserver.json
```
```bash
bun shadcn@latest add https://shadcn-ahooks.vercel.app/r/useMutationObserver.json
```
A hook that provides the ability to watch for changes being made to the DOM tree, refer to [MutationObserver](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver)
## Examples
### Default Usage
{
const [width, setWidth] = useState(200);
const [count, setCount] = useState(0);
const ref = useRef(null);
useMutationObserver(
(mutationsList) => {
mutationsList.forEach(() => setCount((c) => c + 1));
},
ref,
{ attributes: true },
);
return (
current width:{width}
setWidth((w) => w + 10)}>widening
Mutation count {count}
);
};
export default Example;`}
/>
## API
```typescript
useMutationObserver(
callback: MutationCallback,
target: Target,
options?: MutationObserverInit,
);
```
## Params
| Property | Description | Type | Default |
| -------- | --------------------- | ------------------------------------------------------------------- | ------- |
| target | DOM element or ref | `() => Element` \| `Element` \| `MutableRefObject` | - |
| callback | The callback function | `(mutations: MutationRecord[], observer: MutationObserver) => void` | - |
| options | Setting | `MutationObserverInit` | - |
### Options
For options, please refer to [MutationObserver](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver/observe#parameters)
# useNetwork (/docs/useNetwork)
## Overview
A hook that tracks the state of network connection.
[Documentation and Examples](https://ahooks.js.org/hooks/use-network)
## Installation
```bash
pnpm dlx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useNetwork.json
```
```bash
npx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useNetwork.json
```
```bash
yarn shadcn@latest add https://shadcn-ahooks.vercel.app/r/useNetwork.json
```
```bash
bun shadcn@latest add https://shadcn-ahooks.vercel.app/r/useNetwork.json
```
A hook that tracks the state of network connection.
## Examples
### Default usage
{
const networkState = useNetwork();
return (
Network information:
{JSON.stringify(networkState, null, 2)}
);
};
export default Example;`}
/>
## API
```typescript
interface NetworkState {
online?: boolean;
since?: Date;
rtt?: number;
type?: string;
downlink?: number;
saveData?: boolean;
downlinkMax?: number;
effectiveType?: string;
}
const result: NetworkState = useNetwork();
```
### Result
| Property | Description | Type |
| ------------- | -------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| online | Whether connected to network | `boolean` |
| since | `online` latest update time | `Date` |
| rtt | The effective round-trip time estimate in milliseconds | `number` |
| type | The connection type that the user agent is using | `bluetooth` \| `cellular` \| `ethernet` \| `none` \| `wifi` \| `wimax` \| `other` \| `unknown` |
| downlink | The effective bandwidth estimate in megabits per second, | `number` |
| downlinkMax | An upper bound on the downlink speed of the first network hop | `number` |
| saveData | Whether the user agent has set the option to reduce data usage | `boolean` |
| effectiveType | The effective connection type | `slow-2g` \| `2g` \| `3g` \| `4g` |
More information refer to [MDN NetworkInformation](https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation)
# usePagination (/docs/usePagination)
## Overview
`usePagination` is implemented based on `useRequest` and encapsulates common paging logic. The differences from `useRequest` are as follows:
[Documentation and Examples](https://ahooks.js.org/hooks/use-pagination)
## Installation
```bash
pnpm dlx shadcn@latest add https://shadcn-ahooks.vercel.app/r/usePagination.json
```
```bash
npx shadcn@latest add https://shadcn-ahooks.vercel.app/r/usePagination.json
```
```bash
yarn shadcn@latest add https://shadcn-ahooks.vercel.app/r/usePagination.json
```
```bash
bun shadcn@latest add https://shadcn-ahooks.vercel.app/r/usePagination.json
```
`usePagination` is implemented based on `useRequest` and encapsulates common paging logic. The differences from `useRequest` are as follows:
1. The first parameter of `service` is `{ current: number, pageSize: number }`
2. The data structure returned by `service` is `{ total: number, list: Item[] }`
3. It will additionally return the `pagination` field, which contains all the pagination information and functions to operate the pagination.
4. When `refreshDeps` changes, it will reset `current` to the first page and re-initiate the request. Generally, you can put the conditions that `pagination` depends on here
## Examples
### Basic usage
The default usage is the same as `useRequest`, but an additional `pagination` parameter will be returned, which contains all pagination information and functions to operate pagination.
```tsx
import { usePagination } from 'ahooks';
import { Pagination } from 'antd';
import Mock from 'mockjs';
import React from 'react';
interface UserListItem {
id: string;
name: string;
gender: 'male' | 'female';
email: string;
disabled: boolean;
}
const userList = (current: number, pageSize: number) =>
Mock.mock({
total: 55,
[`list|${pageSize}`]: [
{
id: '@guid',
name: '@name',
'gender|1': ['male', 'female'],
email: '@email',
disabled: false,
},
],
});
async function getUserList(params: {
current: number;
pageSize: number;
}): Promise<{ total: number; list: UserListItem[] }> {
return new Promise((resolve) => {
setTimeout(() => {
resolve(userList(params.current, params.pageSize));
}, 1000);
});
}
const Example = () => {
const { data, loading, pagination } = usePagination(getUserList);
return (
{loading ? (
loading
) : (
{data?.list?.map((item) => (
{item.name} - {item.email}
))}
)}
);
};
export default Example;
```
### More parameters
The following code demonstrates that the gender parameter is added. When the gender is modified, the paging is reset to the first page and the data is requested again.
```tsx
import { Pagination } from 'antd';
import Mock from 'mockjs';
import React, { useEffect, useState } from 'react';
import { usePagination } from 'ahooks';
interface UserListItem {
id: string;
name: string;
gender: 'male' | 'female';
email: string;
disabled: boolean;
}
const userList = (current: number, pageSize: number) =>
Mock.mock({
total: 55,
[`list|${pageSize}`]: [
{
id: '@guid',
name: '@name',
'gender|1': ['male', 'female'],
email: '@email',
disabled: false,
},
],
});
async function getUserList(params: {
current: number;
pageSize: number;
gender: string;
}): Promise<{ total: number; list: UserListItem[] }> {
return new Promise((resolve) => {
setTimeout(() => {
resolve(userList(params.current, params.pageSize));
}, 1000);
});
}
export default () => {
const [gender, setGender] = useState('male');
const { data, loading, pagination, run, params } = usePagination(
({ current, pageSize }, g: string) => {
return getUserList({
current,
pageSize,
gender: g,
});
},
{
manual: true,
},
);
useEffect(() => {
run(
{
current: 1,
pageSize: params[0]?.pageSize || 10,
},
gender,
);
}, [gender]);
return (
setGender(e.target.value)}
placeholder="select gender"
>
male
female
{loading ? (
loading
) : (
{data?.list?.map((item) => (
{item.name} - {item.email}
))}
)}
);
};
```
### refreshDeps
`refreshDeps` is a syntactic sugar. When it changes, it will reset the page to the first page and request data again. Generally, you can put the dependent conditions here. The following example implements the previous function more conveniently through `refreshDeps`.
```tsx
import { usePagination } from 'ahooks';
import { useUpdateEffect } from 'ahooks';
import { Pagination } from 'antd';
import Mock from 'mockjs';
import React, { useState } from 'react';
interface UserListItem {
id: string;
name: string;
gender: 'male' | 'female';
email: string;
disabled: boolean;
}
const userList = (current: number, pageSize: number) =>
Mock.mock({
total: 55,
[`list|${pageSize}`]: [
{
id: '@guid',
name: '@name',
'gender|1': ['male', 'female'],
email: '@email',
disabled: false,
},
],
});
async function getUserList(params: {
current: number;
pageSize: number;
gender: string;
}): Promise<{ total: number; list: UserListItem[] }> {
return new Promise((resolve) => {
setTimeout(() => {
resolve(userList(params.current, params.pageSize));
}, 1000);
});
}
export default () => {
const [gender, setGender] = useState('male');
const { data, loading, pagination } = usePagination(
({ current, pageSize }) => {
return getUserList({
current,
pageSize,
gender,
});
},
{
refreshDeps: [gender],
},
);
return (
setGender(e.target.value)}
placeholder="select gender"
>
male
female
{loading ? (
loading
) : (
{data?.list?.map((item) => (
{item.name} - {item.email}
))}
)}
);
};
```
### Cache
Through the `params` caching capability of `useRequest`, we can cache paging data and other conditions.
```tsx
import { useBoolean, useUpdateEffect } from 'ahooks';
import { Pagination } from 'antd';
import Mock from 'mockjs';
import React, { useState } from 'react';
import { usePagination } from 'ahooks';
interface UserListItem {
id: string;
name: string;
gender: 'male' | 'female';
email: string;
disabled: boolean;
}
const userList = (current: number, pageSize: number) =>
Mock.mock({
total: 55,
[`list|${pageSize}`]: [
{
id: '@guid',
name: '@name',
'gender|1': ['male', 'female'],
email: '@email',
disabled: false,
},
],
});
async function getUserList(params: {
current: number;
pageSize: number;
gender: string;
}): Promise<{ total: number; list: UserListItem[] }> {
console.log('cache demo', params.current, params.pageSize, params.gender);
return new Promise((resolve) => {
setTimeout(() => {
resolve(userList(params.current, params.pageSize));
}, 1000);
});
}
const PaginationComponent: React.FC = () => {
const { data, loading, pagination, run, params } = usePagination(
({ current, pageSize }, g: string) => {
return getUserList({
current,
pageSize,
gender: g,
});
},
{
cacheKey: 'userList',
},
);
const [gender, setGender] = useState(params[1] || 'male');
useUpdateEffect(() => {
run(
{
current: 1,
pageSize: params[0]?.pageSize || 10,
},
gender,
);
}, [gender]);
return (
setGender(e.target.value)}
placeholder="select gender"
>
male
female
{loading && !data ? (
loading
) : (
{data?.list?.map((item) => (
{item.name} - {item.email}
))}
)}
);
};
export default () => {
const [state, { toggle }] = useBoolean();
return (
You can click the button multiple times, the conditions of pagination will be cached.
toggle()}>
show/hide
{state &&
}
);
};
```
## API
All parameters and returned results of `useRequest` are applicable to `usePagination`, so we won't repeat them here.
```typescript
type Data = { total: number; list: T[] };
type Params = [{ current: number; pageSize: number, [key: string]: any }, ...any[]];
const {
...,
pagination: {
current: number;
pageSize: number;
total: number;
totalPage: number;
onChange: (current: number, pageSize: number) => void;
changeCurrent: (current: number) => void;
changePageSize: (pageSize: number) => void;
}
} = usePagination(
service: (...args: TParams) => Promise,
{
...,
defaultPageSize?: number;
refreshDeps?: any[];
}
);
```
### Result
| Property | Description | Type |
| ---------- | ------------------------------------------- | ---- |
| pagination | Paging data and methods of paging operation | `-` |
### Params
| Property | Description | Type | Default |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------- | ------- |
| defaultPageSize | Default page size | `number` | 10 |
| defaultCurrent | Number of pages on initial request | `number` | 1 |
| refreshDeps | Changes in `refreshDeps` will reset current to the first page and re-initiate the request. Generally, you can put the dependent conditions here. | `React.DependencyList` | `[]` |
# usePrevious (/docs/usePrevious)
## Overview
A Hook to return the previous state.
[Documentation and Examples](https://ahooks.js.org/hooks/use-previous)
## Installation
```bash
pnpm dlx shadcn@latest add https://shadcn-ahooks.vercel.app/r/usePrevious.json
```
```bash
npx shadcn@latest add https://shadcn-ahooks.vercel.app/r/usePrevious.json
```
```bash
yarn shadcn@latest add https://shadcn-ahooks.vercel.app/r/usePrevious.json
```
```bash
bun shadcn@latest add https://shadcn-ahooks.vercel.app/r/usePrevious.json
```
A Hook to return the previous state.
## Examples
### Default usage
{
const [count, setCount] = useState(0);
const previous = usePrevious(count);
return (
<>
counter current value: {count}
counter previous value: {previous}
setCount((c) => c + 1)}>
increase
setCount((c) => c - 1)}>
decrease
>
);
};
export default Example;`}
/>
### Custom shouldUpdate function
{
if (!prev) {
return true;
}
if (prev.name !== next.name) {
return true;
}
return false;
};
const jobCompareFunction = (prev: Person | undefined, next: Person) => {
if (!prev) {
return true;
}
if (prev.job !== next.job) {
return true;
}
return false;
};
const Example = () => {
const [state, setState] = useState({ name: 'Jack', job: 'student' });
const [nameInput, setNameInput] = useState('');
const [jobInput, setJobInput] = useState('');
const previousName = usePrevious(state, nameCompareFunction);
const previousJob = usePrevious(state, jobCompareFunction);
return (
<>
current name: {state.name}
current job: {state.job}
previous name: {(previousName || {}).name}
previous job: {(previousJob || {}).job}
setNameInput(e.target.value)}
placeholder="new name"
/>
{
setState((s) => ({ ...s, name: nameInput }));
}}
style={{ marginLeft: 8 }}
>
update
setJobInput(e.target.value)}
placeholder="new job"
/>
{
setState((s) => ({ ...s, job: jobInput }));
}}
style={{ marginLeft: 8 }}
>
update
>
);
};
export default Example;`}
/>
## API
```typescript
const previousState: T = usePrevious(
state: T,
shouldUpdate?: (prev: T | undefined, next: T) => boolean
);
```
### Result
| Property | Description | Type |
| ------------- | ------------------ | ---- |
| previousState | The previous value | `T` |
### Params
| Property | Description | Type | Default |
| ------------ | ------------------------------------------------------------- | -------------------------------------------- | ---------------------------- |
| state | The state that needs to be tracked | `T` | - |
| shouldUpdate | Optional. Customize whether the state value should be updated | `(prev: T \| undefined, next: T) => boolean` | `(a, b) => !Object.is(a, b)` |
# useRafInterval (/docs/useRafInterval)
## Overview
A hook implements with `requestAnimationFrame` for better performance. The API is consistent with `useInterval`, the advantage is that the execution of the timer can be stopped when the page is not rendering, such as page hiding or minimization.
[Documentation and Examples](https://ahooks.js.org/hooks/use-rafinterval)
## Installation
```bash
pnpm dlx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useRafInterval.json
```
```bash
npx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useRafInterval.json
```
```bash
yarn shadcn@latest add https://shadcn-ahooks.vercel.app/r/useRafInterval.json
```
```bash
bun shadcn@latest add https://shadcn-ahooks.vercel.app/r/useRafInterval.json
```
A hook implements with `requestAnimationFrame` for better performance. The API is consistent with `useInterval`, the advantage is that the execution of the timer can be stopped when the page is not rendering, such as page hiding or minimization.
Please note that the following two cases are likely to be inapplicable, and `useInterval` is preferred:
* the time interval is less than `16ms`
* want to execute the timer when page is not rendering;
> `requestAnimationFrame` will automatically downgrade to `setInterval` in node environment
## Examples
### Default usage
{
const [count, setCount] = useState(0);
useRafInterval(() => {
setCount(count + 1);
}, 1000);
return count: {count}
;
};
export default Example;`}
/>
### Advanced usage
{
const [count, setCount] = useState(0);
const [interval, setInterval] = useState(1000);
const clear = useRafInterval(() => {
setCount(count + 1);
}, interval);
return (
count: {count}
interval: {interval}
setInterval((t) => (!!t ? t + 1000 : 1000))}
style={{ marginRight: 8 }}
>
interval + 1000
{
setInterval(1000);
}}
>
reset interval
{
clear();
}}
>
clear
);
};
export default Example;`}
/>
## API
```typescript
useRafInterval(
fn: () => void,
delay?: number | undefined,
options?: Options
): fn: () => void;
```
### Params
| Property | Description | Type |
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- |
| fn | The function to be executed every `delay` milliseconds. | `() => void` |
| delay | The time in milliseconds, the timer should delay in between executions of the specified function. The timer will be cancelled if delay is set to `undefined`. | `number` \| `undefined` |
| options | Config of the interval behavior. | `Options` |
### Options
| Property | Description | Type | Default |
| --------- | ---------------------------------------------------------------------- | --------- | ------- |
| immediate | Whether the function should be executed immediately on first execution | `boolean` | `false` |
### Result
| Property | Description | Type |
| ------------- | -------------- | ------------ |
| clearInterval | clear interval | `() => void` |
# useRafState (/docs/useRafState)
## Overview
Update the state in [requestAnimationFrame](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame) callback, generally used for performance optimization.
[Documentation and Examples](https://ahooks.js.org/hooks/use-rafstate)
## Installation
```bash
pnpm dlx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useRafState.json
```
```bash
npx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useRafState.json
```
```bash
yarn shadcn@latest add https://shadcn-ahooks.vercel.app/r/useRafState.json
```
```bash
bun shadcn@latest add https://shadcn-ahooks.vercel.app/r/useRafState.json
```
Update the state in [requestAnimationFrame](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame) callback, generally used for performance optimization.
## Examples
### Default usage
{
const [state, setState] = useRafState({
width: 0,
height: 0,
});
useEffect(() => {
const onResize = () => {
setState({
width: document.documentElement.clientWidth,
height: document.documentElement.clientHeight,
});
};
onResize();
window.addEventListener('resize', onResize);
return () => {
window.removeEventListener('resize', onResize);
};
}, []);
return (
Try to resize the window
current: {JSON.stringify(state)}
);
};
export default Example;`}
/>
### API
Same as `React.useState`.
# useRafTimeout (/docs/useRafTimeout)
## Overview
A hook implements with `requestAnimationFrame` for better performance. The API is consistent with `useTimeout`. the advantage is that will not trigger function when the page is not rendering, such as page hiding or minimization.
[Documentation and Examples](https://ahooks.js.org/hooks/use-raftimeout)
## Installation
```bash
pnpm dlx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useRafTimeout.json
```
```bash
npx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useRafTimeout.json
```
```bash
yarn shadcn@latest add https://shadcn-ahooks.vercel.app/r/useRafTimeout.json
```
```bash
bun shadcn@latest add https://shadcn-ahooks.vercel.app/r/useRafTimeout.json
```
A hook implements with `requestAnimationFrame` for better performance. The API is consistent with `useTimeout`. the advantage is that will not trigger function when the page is not rendering, such as page hiding or minimization.
> `requestAnimationFrame` will automatically downgrade to `setTimeout` in node environment
## Examples
### Default usage
{
const [count, setCount] = useState(0);
useRafTimeout(() => {
setCount(count + 1);
}, 2000);
return count: {count}
;
};
export default Example;`}
/>
### Advanced usage
{
const [count, setCount] = useState(0);
const [delay, setDelay] = useState(1000);
const clear = useRafTimeout(() => {
setCount(count + 1);
}, delay);
return (
count: {count}
Delay: {delay}
setDelay((t) => (!!t ? t + 1000 : 1000))} style={{ marginRight: 8 }}>
Delay + 1000
{
setDelay(1000);
}}
>
reset Delay
{
clear();
}}
>
clear
);
};
export default Example;`}
/>
## API
```typescript
useRafTimeout(
fn: () => void,
delay?: number | undefined,
): fn: () => void;
```
### Params
| Property | Description | Type |
| -------- | ---------------------------------------------------------------------------------------------------------------------- | ----------------------- |
| fn | The function to be executed after `delay` milliseconds. | `() => void` |
| delay | The number of milliseconds to wait before executing the function. The timer will be cancelled if delay is `undefined`. | `number` \| `undefined` |
### Result
| Property | Description | Type |
| ------------ | ------------- | ------------ |
| clearTimeout | clear timeout | `() => void` |
# useReactive (/docs/useReactive)
## Overview
A React hook from ahooks library
[Documentation and Examples](https://ahooks.js.org/hooks/use-reactive)
## Installation
```bash
pnpm dlx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useReactive.json
```
```bash
npx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useReactive.json
```
```bash
yarn shadcn@latest add https://shadcn-ahooks.vercel.app/r/useReactive.json
```
```bash
bun shadcn@latest add https://shadcn-ahooks.vercel.app/r/useReactive.json
```
It offers data reactivity when manipulating states and views, in which case `useState` is unnecessary for state definition. Modifying properties will automatically lead to view rerendering.
## Examples
### Default Usage
{
const state = useReactive({
count: 0,
inputVal: '',
obj: {
value: '',
},
});
return (
);
};
export default Example;`}
/>
### Array
{
const state = useReactive<{ arr: number[] }>({
arr: [],
});
return (
state.arr: {JSON.stringify(state.arr)}
state.arr.push(Math.floor(Math.random() * 100))}
role="pushbtn"
>
push
state.arr.pop()} role="popbtn">
pop
state.arr.shift()} role="shiftbtn">
shift
state.arr.unshift(Math.floor(Math.random() * 100))}
>
unshift
state.arr.reverse()}>
reverse
state.arr.sort()}>
sort
);
};
export default Example;`}
/>
### Computed Properties
{
const state = useReactive({
bug: '',
bugs: ['feat', 'fix', 'chore'],
addBug(bug) {
this.bugs.push(bug);
},
get bugsCount() {
return this.bugs.length;
},
});
return (
state.bugsCount: {state.bugsCount}
{state.bugs.map((bug) => (
{bug}
))}
);
};
export default Example;`}
/>
### Notice
{
const state = useReactive({ count: 0 });
const [stateCount, setStateCount] = useState(0);
const state2 = useReactive({ count: 0 });
const [stateCount2, setStateCount2] = useState(0);
// Depends on the object, because it is always the same reference, it will not be executed
useEffect(() => {
setStateCount(stateCount + 1);
}, [state]);
// Depends on the underlying data type, so as long as it changes, it will be re-executed
useEffect(() => {
setStateCount2(stateCount2 + 1);
}, [state2.count]);
return (
(state.count += 1)}>
stateCount + 1
stateCount:{stateCount}
(state2.count += 1)}>
stateCount2 + 1
stateCount2:{stateCount2}
);
};
export default Example;`}
/>
## API
```js
const state = useReactive(initialValue: Record);
```
## Params
| Params | Description | Type | Default |
| ------------ | ------------- | --------------------- | ------- |
| initialState | Current state | `Record` | - |
## FAQ
### When `useReactive` is used with `Map`, `Set`, it will throw an error or not work?
`useReactive` is not compatible with `Map`, `Set`。
Related issues: [#2239](https://github.com/alibaba/hooks/discussions/2239)
# useResetState (/docs/useResetState)
## Overview
useResetState works similar to `React.useState`, it provides a `reset` method
[Documentation and Examples](https://ahooks.js.org/hooks/use-resetstate)
## Installation
```bash
pnpm dlx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useResetState.json
```
```bash
npx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useResetState.json
```
```bash
yarn shadcn@latest add https://shadcn-ahooks.vercel.app/r/useResetState.json
```
```bash
bun shadcn@latest add https://shadcn-ahooks.vercel.app/r/useResetState.json
```
useResetState works similar to `React.useState`, it provides a `reset` method
## Examples
### Default Usage
{
const initialValue = {
hello: '',
value: Math.random(),
};
const initialValueMemo = useMemo(() => {
return initialValue;
}, []);
const [state, setState, resetState] = useResetState(initialValue);
return (
initial state:
{JSON.stringify(initialValueMemo, null, 2)}
current state:
{JSON.stringify(state, null, 2)}
setState(() => ({
hello: 'world',
value: Math.random(),
}))
}
>
set hello and value
resetState
);
};
export default Example;`}
/>
## API
```typescript
const [state, setState, resetState] = useResetState(
initialState: S | (() => S),
): [S, Dispatch>, () => void]
```
# useResponsive (/docs/useResponsive)
## Overview
React Hook for getting responsive info.
[Documentation and Examples](https://ahooks.js.org/hooks/use-responsive)
## Installation
```bash
pnpm dlx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useResponsive.json
```
```bash
npx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useResponsive.json
```
```bash
yarn shadcn@latest add https://shadcn-ahooks.vercel.app/r/useResponsive.json
```
```bash
bun shadcn@latest add https://shadcn-ahooks.vercel.app/r/useResponsive.json
```
React Hook for getting responsive info.
## Examples
### Get responsive info in components
{
const responsive = useResponsive();
return (
<>
Please change the width of the browser window to see the effect:
{Object.keys(responsive).map((key) => (
{key} {responsive[key] ? '✔' : '✘'}
))}
>
);
};
export default Example;`}
/>
## API
```typescript
interface ResponsiveConfig {
[key: string]: number;
}
interface ResponsiveInfo {
[key: string]: boolean;
}
function configResponsive(config: ResponsiveConfig): void;
function useResponsive(): ResponsiveInfo;
```
### Config
The default config is the same as bootstrap:
```javascript
{
'xs': 0,
'sm': 576,
'md': 768,
'lg': 992,
'xl': 1200,
}
```
If you want to config your own responsive breakpoints, you can use `configResponsive`:
(Caution: You only need to config it once. Don't call this config function repeatedly.)
```javascript
configResponsive({
small: 0,
middle: 800,
large: 1200,
});
```
# useSafeState (/docs/useSafeState)
## Overview
It is exactly the same with `React.useState` , but after the component is unmounted, the `setState` in the asynchronous callback will no longer be executed to avoid memory leakage caused by updating the state after the component is unmounted.
[Documentation and Examples](https://ahooks.js.org/hooks/use-safestate)
## Installation
```bash
pnpm dlx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useSafeState.json
```
```bash
npx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useSafeState.json
```
```bash
yarn shadcn@latest add https://shadcn-ahooks.vercel.app/r/useSafeState.json
```
```bash
bun shadcn@latest add https://shadcn-ahooks.vercel.app/r/useSafeState.json
```
It is exactly the same with `React.useState` , but after the component is unmounted, the `setState` in the asynchronous callback will no longer be executed to avoid memory leakage caused by updating the state after the component is unmounted.
## Examples
### Basic usage
{
const [value, setValue] = useSafeState();
useEffect(() => {
setTimeout(() => {
setValue('data loaded from server');
}, 5000);
}, []);
const text = value || 'Loading...';
return {text}
;
};
const Example = () => {
const [visible, setVisible] = useState(true);
return (
setVisible(false)}>Unmount
{visible && }
);
};
export default Example;`}
/>
## API
```typescript
const [state, setState] = useSafeState(initialState);
```
# useScroll (/docs/useScroll)
## Overview
Get the scroll position of an element.
[Documentation and Examples](https://ahooks.js.org/hooks/use-scroll)
## Installation
```bash
pnpm dlx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useScroll.json
```
```bash
npx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useScroll.json
```
```bash
yarn shadcn@latest add https://shadcn-ahooks.vercel.app/r/useScroll.json
```
```bash
bun shadcn@latest add https://shadcn-ahooks.vercel.app/r/useScroll.json
```
Get the scroll position of an element.
## Examples
### Basic Usage
{
const ref = useRef(null);
const scroll = useScroll(ref);
return (
<>
{JSON.stringify(scroll)}
Lorem ipsum dolor sit amet, consectetur adipisicing elit. A aspernatur atque, debitis ex
excepturi explicabo iste iure labore molestiae neque optio perspiciatis
Aspernatur cupiditate, deleniti id incidunt mollitia omnis! A aspernatur assumenda
consequuntur culpa cumque dignissimos enim eos, et fugit natus nemo nesciunt
Alias aut deserunt expedita, inventore maiores minima officia porro rem. Accusamus ducimus
magni modi mollitia nihil nisi provident
Alias aut autem consequuntur doloremque esse facilis id molestiae neque officia placeat,
quia quisquam repellendus reprehenderit.
Adipisci blanditiis facere nam perspiciatis sit soluta ullam! Architecto aut blanditiis,
consectetur corporis cum deserunt distinctio dolore eius est exercitationem
Ab aliquid asperiores assumenda corporis cumque dolorum expedita
Culpa cumque eveniet natus totam! Adipisci, animi at commodi delectus distinctio dolore
earum, eum expedita facilis
Quod sit, temporibus! Amet animi fugit officiis perspiciatis, quis unde. Cumque
dignissimos distinctio, dolor eaque est fugit nisi non pariatur porro possimus, quas quasi
>
);
};
export default Example;`}
/>
### Detect Whole Page Scroll
{
const scroll = useScroll(document);
return (
);
};
export default Example;`}
/>
### Control listen on scroll status
{
const ref = useRef(null);
const scroll = useScroll(ref, (val) => val.top > 100 && val.top < 200);
return (
<>
{JSON.stringify(scroll)}
Lorem ipsum dolor sit amet, consectetur adipisicing elit. A aspernatur atque, debitis ex
excepturi explicabo iste iure labore molestiae neque optio perspiciatis
Aspernatur cupiditate, deleniti id incidunt mollitia omnis! A aspernatur assumenda
consequuntur culpa cumque dignissimos enim eos, et fugit natus nemo nesciunt
Alias aut deserunt expedita, inventore maiores minima officia porro rem. Accusamus ducimus
magni modi mollitia nihil nisi provident
Alias aut autem consequuntur doloremque esse facilis id molestiae neque officia placeat,
quia quisquam repellendus reprehenderit.
Adipisci blanditiis facere nam perspiciatis sit soluta ullam! Architecto aut blanditiis,
consectetur corporis cum deserunt distinctio dolore eius est exercitationem
Ab aliquid asperiores assumenda corporis cumque dolorum expedita
Culpa cumque eveniet natus totam! Adipisci, animi at commodi delectus distinctio dolore
earum, eum expedita facilis
Quod sit, temporibus! Amet animi fugit officiis perspiciatis, quis unde. Cumque
dignissimos distinctio, dolor eaque est fugit nisi non pariatur porro possimus, quas quasi
>
);
};
export default Example;`}
/>
## API
```typescript
const position = useScroll(target, shouldUpdate);
```
### Params
| Property | Description | Type | Default |
| ------------ | ------------------------- | --------------------------------------------------------------------------- | ------------ |
| target | DOM element or ref object | `Element` \| `Document` \| `(() => Element)` \| `MutableRefObject` | `document` |
| shouldUpdate | Whether update position | `({ top: number, left: number }) => boolean` | `() => true` |
### Result
| Property | Description | Type |
| -------- | ------------------------------------------- | -------------------------------------------- |
| position | The current scroll position of the element. | `{ left: number, top: number } \| undefined` |
# useSelections (/docs/useSelections)
## Overview
This hook is used for Checkbox group, supports multiple selection, single selection, select-all, select-none and semi-selected etc.
[Documentation and Examples](https://ahooks.js.org/hooks/use-selections)
## Installation
```bash
pnpm dlx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useSelections.json
```
```bash
npx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useSelections.json
```
```bash
yarn shadcn@latest add https://shadcn-ahooks.vercel.app/r/useSelections.json
```
```bash
bun shadcn@latest add https://shadcn-ahooks.vercel.app/r/useSelections.json
```
This hook is used for Checkbox group, supports multiple selection, single selection, select-all, select-none and semi-selected etc.
## Examples
### Default usage
```tsx
import { Checkbox, Col, Row } from 'antd';
import React, { useMemo, useState } from 'react';
import { useSelections } from 'ahooks';
export default () => {
const [hideOdd, setHideOdd] = useState(false);
const list = useMemo(() => {
if (hideOdd) {
return [2, 4, 6, 8];
}
return [1, 2, 3, 4, 5, 6, 7, 8];
}, [hideOdd]);
const { selected, allSelected, isSelected, toggle, toggleAll, partiallySelected } = useSelections(
list,
{
defaultSelected: [1],
},
);
return (
Selected: {selected.join(',')}
Check all
setHideOdd((v) => !v)}>
Hide Odd
{list.map((o) => (
toggle(o)}>
{o}
))}
);
};
```
### Object array
```tsx
import { Checkbox, Col, Row } from 'antd';
import React, { useMemo, useState } from 'react';
import { useSelections } from 'ahooks';
export default () => {
const [hideOdd, setHideOdd] = useState(false);
const list = useMemo(() => {
if (hideOdd) {
return [2, 4, 6, 8].map((id) => ({ id }));
}
return [1, 2, 3, 4, 5, 6, 7, 8].map((id) => ({ id }));
}, [hideOdd]);
const { selected, allSelected, isSelected, toggle, toggleAll, partiallySelected } = useSelections(
list,
{
defaultSelected: [{ id: 1 }],
itemKey: 'id',
},
);
return (
Selected: {JSON.stringify(selected)}
Check all
setHideOdd((v) => !v)}>
Hide Odd
{list.map((item) => (
toggle(item)}>
{item.id}
))}
);
};
```
### Pagination
```tsx
import { Checkbox, Divider, Pagination, Spin } from 'antd';
import React, { useEffect, useState } from 'react';
import { useSelections } from 'ahooks';
interface DataType {
id: number;
title: string;
}
interface PaginationType {
current: number;
pageSize: number;
total?: number;
}
const dataSource = Array.from({ length: 50 }, (item, index) => ({
id: index,
title: `title ${index}`,
}));
const getDataFromServer = (props: PaginationType) => {
const { current, pageSize } = props;
const data = dataSource.slice((current - 1) * pageSize, current * pageSize);
return new Promise<{
data: DataType[];
total: PaginationType['total'];
}>((resolve) => {
setTimeout(
() =>
resolve({
data,
total: dataSource.length,
}),
500,
);
});
};
export default () => {
const [dataList, setDataList] = useState([]);
const [loading, setLoading] = useState(false);
const [pagination, setPagination] = useState({
current: 1,
pageSize: 10,
total: 0,
});
const getData = async (params: PaginationType) => {
setLoading(true);
const { data, total } = await getDataFromServer(params);
setLoading(false);
setDataList(data);
setPagination({ ...params, total });
};
useEffect(() => {
getData(pagination);
}, []);
const { selected, allSelected, isSelected, toggle, toggleAll, partiallySelected } = useSelections(
dataList,
{
itemKey: 'id',
},
);
return (
{dataList.map((item) => {
const { id, title } = item;
return (
toggle(item)}
checked={isSelected(item)}
>
{title}
);
})}
{
getData({
current: page,
pageSize: size,
});
}}
/>
Check all
Selected: {selected.length}
{!!selected.length && (
<>
{JSON.stringify(selected)}
>
)}
);
};
```
## API
```typescript
interface Options {
defaultSelected?: T[];
itemKey?: string | ((item: T) => Key);
}
// works when >=3.8.0, recommended ✅
const result: Result = useSelections(items: T[], options?: Options);
// works when <4.0.0, will be removed in ahooks 4.0 🙅🏻♀️
const result: Result = useSelections(items: T[], defaultSelected?: T[]);
```
### Params
| Property | Description | Type | Default |
| -------- | ---------------------- | --------- | ------- |
| items | Data items | `T[]` | - |
| options | Optional configuration | `Options` | - |
### Options
| Property | Description | Type | Default |
| --------------- | ----------------------------------------------------------------------------------------------------------------------- | ------------------------------------ | ------- |
| defaultSelected | Default selected data | `T[]` | `[]` |
| itemKey | The unique key of data item. Typically, this parameter needs to be specified when the data source is an array of object | `string` \| `(item: T) => React.Key` | - |
### Result
| Property | Description | Type |
| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
| selected | Selected items | `T[]` |
| allSelected | Is all items selected | `boolean` |
| noneSelected | Is no item selected | `boolean` |
| partiallySelected | Is partially items selected | `boolean` |
| isSelected | Whether item is selected | `(value: T) => boolean` |
| setSelected | Select multiple items. When executed multiple times, the later return value overwrites the previous one, so if you want to merge the results of multiple operations, you need to do this manually: `setSelected((oldArray) => oldArray.concat(newArray))` | `(value: T[]) => void \| (value: (prevState: T[]) => T[]) => void` |
| select | Select single item | `(value: T) => void` |
| unSelect | UnSelect single item | `(value: T) => void` |
| toggle | Toggle single item select status | `(value: T) => void` |
| selectAll | Select all items | `() => void` |
| unSelectAll | UnSelect all items | `() => void` |
| toggleAll | Toggle select all items | `() => void` |
| clearAll | Clear all selected (In general, `clearAll` is equivalent to `unSelectAll`. If the items is dynamic, `clearAll` will clear "all selected data", while `unSelectAll` will only clear "the currently selected data in the items") | `() => void` |
# useSessionStorageState (/docs/useSessionStorageState)
## Overview
A Hook for store state into sessionStorage.
[Documentation and Examples](https://ahooks.js.org/hooks/use-sessionstoragestate)
## Installation
```bash
pnpm dlx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useSessionStorageState.json
```
```bash
npx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useSessionStorageState.json
```
```bash
yarn shadcn@latest add https://shadcn-ahooks.vercel.app/r/useSessionStorageState.json
```
```bash
bun shadcn@latest add https://shadcn-ahooks.vercel.app/r/useSessionStorageState.json
```
A Hook for store state into sessionStorage.
Usage is exactly the same as [useLocalStorageState](./useLocalStorageState).
# useSet (/docs/useSet)
## Overview
A hook that can manage the state of Set.
[Documentation and Examples](https://ahooks.js.org/hooks/use-set)
## Installation
```bash
pnpm dlx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useSet.json
```
```bash
npx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useSet.json
```
```bash
yarn shadcn@latest add https://shadcn-ahooks.vercel.app/r/useSet.json
```
```bash
bun shadcn@latest add https://shadcn-ahooks.vercel.app/r/useSet.json
```
A hook that can manage the state of Set.
## Examples
### Default usage
{
const [set, { add, remove, reset }] = useSet(['Hello']);
return (
add(String(Date.now()))}>
Add Timestamp
remove('Hello')}
disabled={!set.has('Hello')}
style={{ margin: '0 8px' }}
>
Remove Hello
reset()}>
Reset
{JSON.stringify(Array.from(set), null, 2)}
);
};
export default Example;`}
/>
## API
```typescript
const [
set,
{
add,
remove,
reset
}
] = useSet(initialValue);
```
### Result
| Property | Description | Type |
| -------- | ---------------- | ------------------ |
| set | Set object | `Set` |
| add | Add item | `(key: K) => void` |
| remove | Remove item | `(key: K) => void` |
| reset | Reset to default | `() => void` |
### Params
| Property | Description | Type | Default |
| ------------ | --------------------------- | ------------- | ------- |
| initialValue | Optional, set default value | `Iterable` | - |
# useSetState (/docs/useSetState)
## Overview
useSetState works similar to `this.setState` of class component, used to manage the state of object type.
[Documentation and Examples](https://ahooks.js.org/hooks/use-setstate)
## Installation
```bash
pnpm dlx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useSetState.json
```
```bash
npx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useSetState.json
```
```bash
yarn shadcn@latest add https://shadcn-ahooks.vercel.app/r/useSetState.json
```
```bash
bun shadcn@latest add https://shadcn-ahooks.vercel.app/r/useSetState.json
```
useSetState works similar to `this.setState` of class component, used to manage the state of object type.
## Examples
### Default usage
{
const [state, setState] = useSetState({
hello: '',
});
return (
{JSON.stringify(state, null, 2)}
setState({ hello: 'world' })}>
set hello
setState({ foo: 'bar' })} style={{ margin: '0 8px' }}>
set foo
);
};
export default Example;`}
/>
### Updating with callback
{
const [state, setState] = useSetState({
hello: 'world',
count: 0,
});
return (
{JSON.stringify(state, null, 2)}
setState((prev) => ({ count: prev.count + 1 }))}>
count + 1
);
};
export default Example;`}
/>
## API
```typescript
const [state, setState] = useSetState(initialState);
```
### Result
| Property | Description | Type | Default |
| -------- | -------------------- | ----------------------------------------------------------------------------------------- | ------- |
| state | Current state | `T` | - |
| setState | Update current state | `(state: Partial \| null) => void` \| `((prevState: T) => Partial \| null) => void` | - |
### Params
| Property | Description | Type | Default |
| ------------ | ------------- | -------------- | ------- |
| initialState | Initial state | `T \| () => T` | - |
# useSize (/docs/useSize)
## Overview
A hook that observes size change of an element.
[Documentation and Examples](https://ahooks.js.org/hooks/use-size)
## Installation
```bash
pnpm dlx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useSize.json
```
```bash
npx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useSize.json
```
```bash
yarn shadcn@latest add https://shadcn-ahooks.vercel.app/r/useSize.json
```
```bash
bun shadcn@latest add https://shadcn-ahooks.vercel.app/r/useSize.json
```
A hook that observes size change of an element.
## Examples
### Default usage
{
const ref = useRef(null);
const size = useSize(ref);
return (
Try to resize the preview window
width: {size?.width}px, height: {size?.height}px
);
};
export default Example;`}
/>
### Pass in the DOM element
{
const size = useSize(document.querySelector('body'));
return (
Try to resize the preview window
width: {size?.width}px, height: {size?.height}px
);
};
export default Example;`}
/>
## API
```typescript
const size = useSize(target);
```
### Params
| Property | Description | Type | Default |
| -------- | ------------------------- | ------------------------------------------------------------- | ------- |
| target | DOM element or ref object | `Element` \| `(() => Element)` \| `MutableRefObject` | - |
### Result
| Property | Description | Type | Default |
| -------- | ------------------- | ------------------------------------------------ | ------------------------------------------------------------------------- |
| size | Size of the element | `{ width: number, height: number } \| undefined` | `{ width: target.clientWidth, height: target.clientHeight } \| undefined` |
# useTextSelection (/docs/useTextSelection)
## Overview
Tracking content, size, position of user text selection.
[Documentation and Examples](https://ahooks.js.org/hooks/use-textselection)
## Installation
```bash
pnpm dlx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useTextSelection.json
```
```bash
npx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useTextSelection.json
```
```bash
yarn shadcn@latest add https://shadcn-ahooks.vercel.app/r/useTextSelection.json
```
```bash
bun shadcn@latest add https://shadcn-ahooks.vercel.app/r/useTextSelection.json
```
Tracking content, size, position of user text selection.
## Examples
### Default usage
{
const { text } = useTextSelection();
return (
You can select text all page.
Result:{text}
);
};
export default Example;`}
/>
### Listen for specified area
{
const ref = useRef(null);
const selection = useTextSelection(ref);
return (
Please swipe your mouse to select any text on this paragraph.
Result:{JSON.stringify(selection)}
);
};
export default Example;`}
/>
### Translate user text selection
```tsx
import { useRequest, useTextSelection } from 'ahooks';
import { Popover, Spin } from 'antd';
import React, { useEffect, useState } from 'react';
const getResult = (keyword: string): Promise => {
const trimedText = keyword.trim() !== '';
if (!trimedText) {
return Promise.resolve('');
}
return new Promise((resolve) => {
setTimeout(() => resolve(`[translate result] ${keyword}`), 2000);
});
};
export default () => {
const {
text = '',
left = 0,
top = 0,
height = 0,
width = 0,
} = useTextSelection(() => document.querySelector('#translate-dom'));
const [open, setOpen] = useState(false);
const { data, run, loading } = useRequest(getResult, {
manual: true,
});
useEffect(() => {
if (text.trim() === '') {
setOpen(false);
return;
}
setOpen(true);
run(text);
}, [text]);
return (
Translation of this paragraph;Translation of this paragraph;Translation of this paragraph;
{loading ? 'Translating……' : data}}
open={open}
>
);
};
```
## API
```typescript
const state = useTextSelection(target?);
```
### Params
| Property | Description | Type | Default |
| -------- | ------------------ | ------------------------------------------------------------------------------------ | ---------- |
| target | DOM element or ref | `Element` \| `Document` \| `(() => Element\Document)` \| `MutableRefObject` | `document` |
### Result
| Property | Description | Type |
| -------- | ---------------------------------------------- | ------- |
| state | Content, size, position of user text selection | `State` |
### State
| Property | Description | Type |
| -------- | ----------------------------------- | -------- |
| text | Selected text | `string` |
| left | The left coordinate value of text | `number` |
| right | The right coordinate value of text | `number` |
| top | The top coordinate value of text | `number` |
| bottom | The bottom coordinate value of text | `number` |
| height | The height of text | `number` |
| width | The width of text | `number` |
# useTheme (/docs/useTheme)
## Overview
This hook is used to get and set the theme, and store the `themeMode` into `localStorage`.
[Documentation and Examples](https://ahooks.js.org/hooks/use-theme)
## Installation
```bash
pnpm dlx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useTheme.json
```
```bash
npx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useTheme.json
```
```bash
yarn shadcn@latest add https://shadcn-ahooks.vercel.app/r/useTheme.json
```
```bash
bun shadcn@latest add https://shadcn-ahooks.vercel.app/r/useTheme.json
```
This hook is used to get and set the theme, and store the `themeMode` into `localStorage`.
## Examples
### Default usage
{
const { theme, themeMode, setThemeMode } = useTheme({
localStorageKey: 'themeMode',
});
return (
<>
theme: {theme}
themeMode: {themeMode}
{
setThemeMode('dark');
}}
>
use dark theme
{
setThemeMode('light');
}}
>
use light theme
{
setThemeMode('system');
}}
>
follow the system
>
);
};
export default Example;`}
/>
## API
```typescript
const { theme, themeMode, setThemeMode } = useTheme({
localStorageKey?: string;
});
```
### Params
| Property | Description | Type | Default |
| --------------- | ---------------------------------------------------- | -------- | ----------- |
| localStorageKey | The key in localStorage to store selected theme mode | `string` | `undefined` |
### Result
| Property | Description | Type | Default |
| ------------ | --------------------- | ----------------------------------------------- | ------------------------------------------------------------------------------------ |
| theme | current display theme | `"light" \| "dark"` | if themeMode is "system" then equals to system setting,otherwise equals to themeMode |
| themeMode | selected theme mode | `"light" \| "dark" \| "system"` | equals to localStorage "themeMode", otherwise equals to "system" |
| setThemeMode | select theme mode | `(mode: "light" \| "dark" \| "system") => void` | |
# useThrottle (/docs/useThrottle)
## Overview
A hook that deal with the throttled value.
[Documentation and Examples](https://ahooks.js.org/hooks/use-throttle)
## Installation