en-US
This example shows how to load data remotely.
zh-CN
该示例展示了如何实现远程加载数据。
import { useState, useEffect, useRef } from 'react';
import { useImmer, useAsync } from '@react-devui/hooks';
import { DTable, DButton, DSeparator, DSpinner, DPagination } from '@react-devui/ui';
const remoteData = Array.from({ length: 100 }).map((_, i) => ({
name: `Name ${i + 1}`,
age: `${i % 30}`,
address: `Room 100${i}, Building 2, Fandou Garden, Fandou Street`,
}));
const filterList = {
name: Array.from({ length: 6 }).map((_, i) => ({ label: `Name ${i + 1}`, value: `Name ${i + 1}` })),
};
export default function Demo() {
const dataRef = useRef({});
const async = useAsync();
const [list, setList] = useState([]);
const [loading, setLoading] = useState(true);
const [page, setPage] = useState(1);
const [pageSize, setPageSize] = useState(10);
const [total, setTotal] = useState(0);
const [sort, setSort] = useImmer({});
const [filter, setFilter] = useImmer({ name: null });
const fetchData = (request: { sort?: 'age' | '-age'; 'filter[name:eq]'?: string; page: number; pageSize: number }) => {
setLoading(true);
request = Object.assign(
{
sort: sort.age === 'ascend' ? 'age' : sort.age === 'descend' ? '-age' : undefined,
'filter[name:eq]': filter.name ? filter.name : undefined,
page,
pageSize,
},
request
);
dataRef.current.clearTid?.();
dataRef.current.clearTid = async.setTimeout(() => {
setLoading(false);
const response = (() => {
const sortFn = (() => {
if (request.sort) {
return (a, b) => (Number(a.age) - Number(b.age)) * (request.sort === 'age' ? 1 : -1);
}
})();
const filterFn = (data) => {
if (request['filter[name:eq]'] && data.name !== request['filter[name:eq]']) {
return false;
}
return true;
};
const list = remoteData.filter(filterFn);
if (sortFn) {
list.sort(sortFn);
}
const meta = {
page:
(request.page - 1) * request.pageSize >= list.length ? Math.max(Math.ceil(list.length / request.pageSize), 1) : request.page,
total: list.length,
};
const data = list.slice((meta.page - 1) * request.pageSize, meta.page * request.pageSize);
return { meta, data };
})();
setList(response.data);
setPage(response.meta.page);
setTotal(response.meta.total);
}, 1000);
};
useEffect(() => {
fetchData({});
}, []);
return (
<DTable>
<DSpinner dVisible={loading}></DSpinner>
<table>
<thead>
<tr>
<DTable.Th
dActions={[
<DTable.Filter
dList={filterList.name}
dSelected={filter.name}
onSelectedChange={(val) => {
setFilter((draft) => {
draft.name = val;
});
fetchData({ 'filter[name:eq]': val ? val : undefined });
}}
/>,
]}
>
Name
</DTable.Th>
<DTable.Th
dSort={{
active: sort.age ?? null,
onSort: (order) => {
setSort({ age: order });
fetchData({ sort: order === 'ascend' ? 'age' : order === 'descend' ? '-age' : undefined });
},
}}
>
Age
</DTable.Th>
<DTable.Th>Address</DTable.Th>
<DTable.Th>Action</DTable.Th>
</tr>
</thead>
<tbody>
{list.length === 0 ? (
<DTable.Empty />
) : (
list.map((data) => (
<tr key={data.name}>
<DTable.Td>{data.name}</DTable.Td>
<DTable.Td>{data.age}</DTable.Td>
<DTable.Td>{data.address}</DTable.Td>
<DTable.Td dNowrap>
<DButton dType="link">Edit</DButton>
<DSeparator dVertical></DSeparator>
<DButton dType="link">Delete</DButton>
</DTable.Td>
</tr>
))
)}
</tbody>
</table>
<DPagination
dActive={page}
dTotal={total}
dPageSize={pageSize}
dCompose={['pages', 'page-size']}
onPaginationChange={(page, pageSize) => {
setPage(page);
setPageSize(pageSize);
fetchData({ page, pageSize });
}}
></DPagination>
</DTable>
);
}