useSelections
This hook is used for Checkbox group, supports multiple selection, single selection, select-all, select-none and semi-selected etc.
Overview
This hook is used for Checkbox group, supports multiple selection, single selection, select-all, select-none and semi-selected etc.
Installation
Open inpnpm dlx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useSelections.jsonnpx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useSelections.jsonyarn shadcn@latest add https://shadcn-ahooks.vercel.app/r/useSelections.jsonbun shadcn@latest add https://shadcn-ahooks.vercel.app/r/useSelections.jsonThis hook is used for Checkbox group, supports multiple selection, single selection, select-all, select-none and semi-selected etc.
Examples
Default usage
import { Checkbox, Col, Row } from 'antd';
import React, { useMemo, useState } from 'react';
import useSelections from '@/src/hooks/ahooks/useSelections';
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 (
<div>
<div>Selected: {selected.join(',')}</div>
<div style={{ borderBottom: '1px solid #E9E9E9', padding: '10px 0' }}>
<Checkbox checked={allSelected} onClick={toggleAll} indeterminate={partiallySelected}>
Check all
</Checkbox>
<Checkbox checked={hideOdd} onClick={() => setHideOdd((v) => !v)}>
Hide Odd
</Checkbox>
</div>
<Row style={{ padding: '10px 0' }}>
{list.map((o) => (
<Col span={12} key={o}>
<Checkbox checked={isSelected(o)} onClick={() => toggle(o)}>
{o}
</Checkbox>
</Col>
))}
</Row>
</div>
);
};Object array
import { Checkbox, Col, Row } from 'antd';
import React, { useMemo, useState } from 'react';
import useSelections from '@/src/hooks/ahooks/useSelections';
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 (
<div>
<div>Selected: {JSON.stringify(selected)}</div>
<div style={{ borderBottom: '1px solid #E9E9E9', padding: '10px 0' }}>
<Checkbox checked={allSelected} onClick={toggleAll} indeterminate={partiallySelected}>
Check all
</Checkbox>
<Checkbox checked={hideOdd} onClick={() => setHideOdd((v) => !v)}>
Hide Odd
</Checkbox>
</div>
<Row style={{ padding: '10px 0' }}>
{list.map((item) => (
<Col span={12} key={item.id}>
<Checkbox checked={isSelected(item)} onClick={() => toggle(item)}>
{item.id}
</Checkbox>
</Col>
))}
</Row>
</div>
);
};Pagination
import { Checkbox, Divider, Pagination, Spin } from 'antd';
import React, { useEffect, useState } from 'react';
import useSelections from '@/src/hooks/ahooks/useSelections';
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<DataType[]>([]);
const [loading, setLoading] = useState<boolean>(false);
const [pagination, setPagination] = useState<PaginationType>({
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 (
<Spin spinning={loading}>
{dataList.map((item) => {
const { id, title } = item;
return (
<div key={id} style={{ display: 'flex', flexDirection: 'row' }}>
<Checkbox
style={{ padding: '4px 8px' }}
onClick={() => toggle(item)}
checked={isSelected(item)}
>
{title}
</Checkbox>
</div>
);
})}
<Pagination
style={{ margin: '12px 0 16px 0' }}
size="small"
showSizeChanger
current={pagination.current}
pageSize={pagination.pageSize}
total={pagination.total}
onChange={(page, size) => {
getData({
current: page,
pageSize: size,
});
}}
/>
<div
style={{
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
paddingLeft: '8px',
}}
>
<Checkbox checked={allSelected} indeterminate={partiallySelected} onClick={toggleAll}>
Check all
</Checkbox>
<span style={{ marginLeft: '90px' }}>Selected: {selected.length}</span>
</div>
{!!selected.length && (
<>
<Divider />
{JSON.stringify(selected)}
</>
)}
</Spin>
);
};API
interface Options<T> {
defaultSelected?: T[];
itemKey?: string | ((item: T) => Key);
}
// works when >=3.8.0, recommended ✅
const result: Result = useSelections<T>(items: T[], options?: Options<T>);
// works when <4.0.0, will be removed in ahooks 4.0 🙅🏻♀️
const result: Result = useSelections<T>(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 |