Installations
npm install @sinoui/use-rest-list-api
Developer Guide
Typescript
No
Module System
CommonJS
Score
67.1
Supply Chain
95.4
Quality
80.4
Maintenance
50
Vulnerability
100
License
Releases
Unable to fetch releases
Contributors
Unable to fetch Contributors
Languages
TypeScript (100%)
Love this project? Help keep it running — sponsor us today! 🚀
Developer
sinoui
Download Statistics
Total Downloads
6,594
Last Day
1
Last Week
8
Last Month
69
Last Year
450
GitHub Statistics
1 Stars
64 Commits
3 Watching
17 Branches
5 Contributors
Bundle Size
81.41 kB
Minified
24.48 kB
Minified + Gzipped
Package Meta Information
Latest Version
1.0.0
Package Id
@sinoui/use-rest-list-api@1.0.0
Unpacked Size
155.32 kB
Size
38.47 kB
File Count
19
Total Downloads
Cumulative downloads
Total Downloads
6,594
Last day
-83.3%
1
Compared to previous day
Last week
-61.9%
8
Compared to previous week
Last month
360%
69
Compared to previous month
Last year
-75.6%
450
Compared to previous year
Daily Downloads
Weekly Downloads
Monthly Downloads
Yearly Downloads
Peer Dependencies
1
use-rest-list-api
不分页列表与 RESTful CRUD API 交互的状态管理
它可以帮助我们:
- 管理列表的查询
- 与 RESTful CRUD API 交互
- 列表数据维护
- 查询条件与浏览器的 url 同步
目录:
安装
1yarn add @sinoui/use-rest-list-api
或者
1npm i --save @sinoui/use-rest-list-api
快速使用
1import React from 'react'; 2import useRestListApi from '@sinoui/use-rest-list-api'; 3 4interface User { 5 userId: string; 6 userName: string; 7} 8 9function ListDemo() { 10 const dataSource = useRestListApi<User>('/apis/users'); 11 12 return ( 13 <div> 14 {dataSource.isLoading && <div>正在加载人员列表数据...</div>} 15 <h1>人员列表</h1> 16 {dataSource.items.map((user) => ( 17 <div key={user.userId}>{user.userName}</div> 18 ))} 19 </div> 20 ); 21}
RESTful CRUD API
假定我们要维护一组人员数据,获取人员列表的 url 是/users
。
获取列表数据
请求
GET /users?sex=male&sort=firstName&sort=lastName,desc
请求参数说明:
sex=male
- 表示列表的过滤条件。@sinoui/use-rest-list-api 默认将过滤条件放在查询字符串中。sort
- 排序,默认格式为propertyName[,asc|desc]
,如果有多个,则按照sort=propertyName&sort=propertyName2,desc
这样的方式编排
注意:这是@sinoui/use-rest-list-api 默认发送分页查询请求的格式,你的 RESTful API 如果不是这样的,那么你需要定制列表查询请求。
响应
后端返回 json 格式数据,数据如下:
1[ 2 { 3 id: '1', 4 firstName: '张', 5 lastName: '三', 6 sex: 'male', 7 }, 8 { 9 id: '2', 10 firstName: '李', 11 lastName: '四', 12 sex: 'male', 13 }, 14];
注意:如果你的 API 响应的数据格式不是这样的,那么你可以定制列表查询响应转换器,将 API 响应数据转换成上面说的数据格式即可。
获取单个数据
有时为了展现详情数据,而列表返回的数据不是很全,这时你就需要通过 API 获取单个数据。
请求
按照 RESTful 风格设计的 API,请求如下:
GET /users/1
响应
返回 JSON 格式数据。
1{ 2 "id": "1", 3 "firstName": "张", 4 "lastName": "三", 5 "sex": "male", 6 "birthday": "1999-01-12" 7}
注意:如果你的 API 响应数据格式不一致,你可以通过定制请求单个数据响应转换器,来转换成这样的数据格式。
新增数据
请求
POST /users
请求参数: (itemInfo: T,isNeedUpdate: boolean = true, idx: number = -1)
1// 要新增的数据 2{ 3 "firstName": "王", 4 "lastName": "五", 5 "sex": "female", 6 "birthday": "2000-08-12" 7}, 8// 新增操作完成之后是否需要刷新页面,默认true 9false, 10// 指定新增数据的插入位置,默认-1,在数据的末尾添加 11-1
注意:如果你的 API 请求要新增的数据格式不一致,你可以通过定制新增请求的数据转换器,将上面的数据格式转换成满足你的 API 的数据格式。
响应
返回 JSON 格式的数据:
1{ 2 "id": "3", 3 "firstName": "王", 4 "lastName": "五", 5 "sex": "female", 6 "birthday": "2000-08-12" 7}
注意:如果你的 API 响应数据格式不一致,你可以通过定制新增响应的数据转换器,将上面的数据格式转换成满足你的 API 的数据格式。
更新数据
请求
PUT /users/3
请求体是 JSON 格式数据:
1{ 2 "id": "3", 3 "firstName": "王", 4 "lastName": "五", 5 "sex": "male", 6 "birthday": "2000-08-12" 7}
注意:如果你的 API 请求数据格式不一致,你可以通过定制更新请求的数据转换器,将上面的数据格式转换成满足你的 API 的数据格式。
响应
返回 JSON 格式的数据:
1{ 2 "id": "3", 3 "firstName": "王", 4 "lastName": "五", 5 "sex": "male", 6 "birthday": "2000-08-12" 7}
注意:如果你的 API 响应数据格式不一致,你可以通过定制更新响应的数据转换器,将上面的数据格式转换成满足你的 API 的数据格式。
删除数据
请求
删除单个数据:
1DELETE / users / 1
删除多条数据:
DELETE /users/1,2,3
注意:如果你的 API 不支持删除多条数据,那么请设置options.useMultiDeleteApi
为false
。
响应
返回 200、201 等 2xx 状态码表示删除成功即可。
数据结构
排序信息
排序:
1interface SortInfo { 2 direction: 'desc' | 'asc'; 3 property: string; 4}
列表查询响应
useRestListApi 默认列表查询的数据结构如下:
1T[]
useRestListApi 参数说明
1const dataSource = useRestListApi<T, PageData>( 2 url: string, 3 defaultValue?: PageData<T>, 4 options?: Options 5);
url
指定加载列表数据的url
,一般为 RESTful CRUD API 中加载列表的url
,也就是基础 url。加载列表数据的 url 与基础 url 不一致,可以通过options.baseUrl
设定基础 url。
defaultValue
指定默认的列表分页数据,默认为:
1T[]
options
配置:
baseUrl
- 指定 curd api 的基础url
,如果不指定,则默认为url
。defaultSearchParams
- 指定默认的查询条件。defaultSort
- 指定默认的排序规则。syncToUrl
- 如果为true
,则会同步查询条件与浏览器 URL。默认为false
。keyName
- 指定唯一键属性名,默认为id
。useMultiDeleteApi
- 是否启动删除多条数据的 API。默认为true
,表示启用。见删除数据章节。transformListResponse
- 指定分页列表查询结果的转换器。transformListRequest
- 指定分页查询条件转换器。transformFetchOneResponse
- 指定获取单条数据的响应数据转换器。transformSaveRequest
- 指定新增数据的请求数据转换器。transformSaveResponse
- 指定新增数据的响应数据转换器。transformUpdateRequest
- 指定更新数据的请求数据转换器。transformUpdateResponse
- 指定更新数据的响应数据转换器。transformRemoveResponse
- 指定删除数据的响应数据转换器。
转换器可以用来定制你的 API 细节。会用一个章节来介绍。
转换器
如果你的 API 数据格式与@sinoui/use-rest-list-api 默认支持的不同,那么你可以使用转换器来实现定制,让@sinoui/use-rest-list-api 为你的 API 服务。
定制列表查询请求
使用transformListRequest
来定制列表查询请求。例如下面的转换器:
1import qs from 'qs'; 2 3export default function transformListRequest( 4 searchParams: { 5 [key: string]: string; 6 }, 7 sorts: SortInfo[], 8) { 9 return qs.stringify( 10 { 11 ...searchParams, 12 sort: sorts.map( 13 (sortInfo) => 14 `${sortInfo.property}${sortInfo.direction === 'desc' ? '_desc' : ''}`, 15 ), 16 }, 17 { 18 arrayFormat: 'comma', 19 }, 20 ); 21}
应用这个转换器后,发送的分页列表查询将会是下面的格式:
GET /users?sex=male&sort=firstName,lastName_desc
推荐使用qs来处理请求参数的序列化和解析。这里用到了arrayFormat配置,设定为comma
,那么遇到数组时,则会采用","的方式将多个数据连接在一起。arrayFormat 的几个参数如下所示:
1qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'indices' }); 2// 'a[0]=b&a[1]=c' 3qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'brackets' }); 4// 'a[]=b&a[]=c' 5qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'repeat' }); 6// 'a=b&a=c' 7qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'comma' }); 8// 'a=b,c'
transformListRequest 方法结构如下:
1interface SearchParams { 2 [key: string]: any; 3} 4 5/** 6 * 转换列表查询的请求 7 * 8 * @param searchParams 查询条件 9 * @param sorts 排序信息 10 * 11 * @return {string} 返回列表查询请求的查询字符串。需要是字符串格式的。 12 */ 13function transformListRequest( 14 searchParams: SearchParams, 15 sorts: SortInfo[], 16): string;
定制列表查询响应转换器
使用transformListResponse
来转换分页列表查询响应的数据格式。如下所示的Hacker News API转换器:
1interface HackerNew { 2 objectID: string; 3 title: string; 4 url: string; 5 auth: string; 6 tags: string[]; 7} 8 9interface HackerNewsListResponse { 10 hits: HackerNew[]; 11 nbHits: number; 12 page: number; 13 nbPages: number; 14 hitsPerPage: number; 15} 16 17function transformListResponse( 18 response: HackerNewsListResponse, 19): PageResponse<HackerNew> { 20 return response.hits, 21}
transformListResponse 函数的结构如下:
1function transformListPresponse<T, Response>( 2 response: Response, 3): PageResponse<T>;
定制请求单个数据响应转换器
使用transformFetchOneResponse
定制请求单个数据响应的数据格式。例如下面的示例:
1interface User { 2 userId: string; 3 firstName: string; 4 lastName: string; 5} 6 7interface Response { 8 result: User; 9 status: boolean; 10} 11 12function transformFetchOneResponse(response: Response): User { 13 return response.result; 14}
transformFetchOneResponse 函数的结构如下:
1function transformFetchOneResponse<T, Response>(respone: Response): T;
定制新增请求的数据转换器
使用transformSaveRequest
定制新增数据请求转换器。例如:
1interface SaveUserInfo { 2 user: User; 3 time: long; 4} 5 6function transformSaveRequest(user: User): SaveUserInfo { 7 return { 8 user, 9 time: new Date().getTime(), 10 }; 11}
transformSaveRequest 函数的数据结构如下:
1function transformSaveRequest<T, NewRequestData>( 2 data: T, 3 headers: { [key: string]: string }, 4): NewRequestData;
定制新增响应的数据转换器
使用transformSaveResponse
定义新增响应的数据格式转变。例如:
1/** 2 * 新增API响应返回数据的结构 3 */ 4interface ResponseData { 5 result: User; 6 status: boolean; 7 errorMessage?: string; 8} 9 10function transformSaveResponse(responseData: ResponseData): User { 11 if (response.status) { 12 return response.result; 13 } 14 15 throw new Error('获取数据失败'); 16}
transformSaveResponse 函数的数据结构如下:
1function transformSaveResponse<T, Response>(response: Response): T;
定制更新请求的数据转换器
使用transformUpdateRequest
定制更新请求。用法与transformSaveRequest一致。
定制更新响应的数据转换器
使用transformUpdateResponse
定制更新请求。用法与transformSaveResponse一致。
定制删除响应的数据转换器
1/** 删除API的响应数据结构 */ 2interface ResponseData { 3 code:string; 4 msg:string; 5} 6 7function transformRemoveResponse(response:ResponseData):void { 8 if(code==='200'){ 9 alert('删除成功'); 10 } else { 11 alert('删除失败'); 12 throw new Error(response.msg); 13 } 14}
dataSource 的属性和方法
1const dataSource = useRestListApi<User, ListRawResponse>('/users');
我们的组件可以通过dataSource
与查询结果、查询条件、RESTful API 进行沟通。
获取查询数据
1 // 获取当前页列表数据 2const users: User[] = dataSource.items; 3 4// 获取id为'1'的用户数据 5const user: User = dataSource.getItemById('1'); 6 7// 更新id为'1'的用户数据 8const newUser = {...user, 'sex': 'female'}; 9dataSource.updateItem(newUser); 10 11// 更新部分字段 12dataSource.setItem('1', 'sex', 'female'); 13dataSource.setItem('1', { birthday: '2000-10-12' }); 14 15//替换items 16dataSource.setItems([{id:'1',birthday:'2019-01-01'},{id:'2',age:32}]) 17 18// 新增 19dataSource.addItem({id: '5', firstName: '赵', lastName: '六'}, false, -1); 20 21// 删除id为'1'的用户数据 22dataSource.removeItemById('3'); 23 24// 删除多条数据 25dataSource.removeItemsByIds(['1', '2', '3']); 26 27// 设置默认查询条件 28dataSource.setDefaultSearchParams({userName:'张三'}); 29 30// 删除指定行的数据,从0开始 31dataSource.removeItemAt(5) 32 33// 获取原始响应数据 34const rawResponse = dataSource.rawResponse; 35 36// 获取是否正在加载列表数据的状态 37const isLoading = dataSource.isLoading; 38 39// 获取是否加载列表数据失败的状态 40const isError = dataSource.isError;
注意:这里介绍的getItemById
、updateItem
、setItem
、addItem
、removeItemById
这些方法只会与dataSource.items
进行交互,不会与 RESTful CRUD API 进行交互。如果需要与 RESTful CRUD API 交互,参见与增删改查 API 交互。
排序
1// 按照姓氏倒序排序 2dataSource.sortWith([ 3 { 4 property: 'firstName', 5 direction: 'desc', 6 }, 7 { 8 property: 'lastName', 9 direction: 'asc', 10 }, 11]);
列表查询
1// 根据查询条件获取数据 2dataSource.query(searchParams); 3 4// 获取查询条件 5dataSource.searchParams; 6// 获取默认的查询条件 7dataSource.defaultSearchParams; 8 9// 重新获取当前页的数据 10dataSource.reload();
fetch()
方法是查询列表的基础方法,它的语法格式如下:
1function fetch<T>( 2 searchParams?: SearchParams, 3 sorts?: SortInfo[], 4): PageResponse<T>;
与增删改查 API 交互
1// 获取id为'1'的数据 2const user = await dataSource.get('1'); 3 4// 新增用户数据 5const user = await dataSource.save( 6 { firstName: '张', lastName: '三' }, 7 false, 8 -1, 9); 10 11// 修改用户数据 12const user = await dataSource.update({ 13 id: '1', 14 firstName: '张', 15 lastName: '三', 16}); 17 18// 删除数据 19await dataSource.remove('1'); 20 21// 删除多条数据 22await dataSource.remove(['1', '2', '3']);
以上操作默认均会修改dataSource.items
。如果不需要更新,则可以指定函数的第二个参数为false
,如:
1const user = await dataSource.get('1', false);
No vulnerabilities found.
Reason
no binaries found in the repo
Reason
license file detected
Details
- Info: project has a license file: LICENSE:0
- Info: FSF or OSI recognized license: MIT License: LICENSE:0
Reason
Found 1/13 approved changesets -- score normalized to 0
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
- Warn: no security policy file detected
- Warn: no security file to analyze
- Warn: no security file to analyze
- Warn: no security file to analyze
Reason
project is not fuzzed
Details
- Warn: no fuzzer integrations found
Reason
branch protection not enabled on development/release branches
Details
- Warn: branch protection not enabled for branch 'master'
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
- Warn: 0 commits out of 18 are checked with a SAST tool
Reason
55 existing vulnerabilities detected
Details
- Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92
- Warn: Project is vulnerable to: GHSA-6chw-6frg-f759
- Warn: Project is vulnerable to: GHSA-v88g-cgmw-v5xw
- Warn: Project is vulnerable to: GHSA-93q8-gq69-wqmw
- Warn: Project is vulnerable to: GHSA-4w2v-q235-vp99
- Warn: Project is vulnerable to: GHSA-cph5-m8f7-6c5x
- Warn: Project is vulnerable to: GHSA-wf5p-g6vw-rhxx
- Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg
- Warn: Project is vulnerable to: GHSA-w8qv-6jwh-64r5
- Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275
- Warn: Project is vulnerable to: GHSA-gxpj-cx7g-858c
- Warn: Project is vulnerable to: GHSA-w573-4hg7-7wgq
- Warn: Project is vulnerable to: GHSA-74fj-2j2h-c42q
- Warn: Project is vulnerable to: GHSA-pw2r-vq6v-hr8c
- Warn: Project is vulnerable to: GHSA-jchw-25xp-jwwc
- Warn: Project is vulnerable to: GHSA-cxjh-pqwp-8mfp
- Warn: Project is vulnerable to: GHSA-8r6j-v8pm-fqw3
- Warn: Project is vulnerable to: MAL-2023-462
- Warn: Project is vulnerable to: GHSA-ww39-953v-wcq6
- Warn: Project is vulnerable to: GHSA-765h-qjxv-5f44
- Warn: Project is vulnerable to: GHSA-f2jv-r9rf-7988
- Warn: Project is vulnerable to: GHSA-43f8-2h32-f4cj
- Warn: Project is vulnerable to: GHSA-33f9-j839-rf8h
- Warn: Project is vulnerable to: GHSA-c36v-fmgq-m8hx
- Warn: Project is vulnerable to: GHSA-896r-f27r-55mw
- Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h
- Warn: Project is vulnerable to: GHSA-6c8f-qphg-qjgp
- Warn: Project is vulnerable to: GHSA-29mw-wpgm-hmr9
- Warn: Project is vulnerable to: GHSA-35jh-r3h4-6jhm
- Warn: Project is vulnerable to: GHSA-r6rj-9ch6-g264
- Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv
- Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3
- Warn: Project is vulnerable to: GHSA-vh95-rmgr-6w4m
- Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h
- Warn: Project is vulnerable to: GHSA-5fw9-fq32-wv5p
- Warn: Project is vulnerable to: GHSA-rp65-9cf3-cjxr
- Warn: Project is vulnerable to: GHSA-hj48-42vr-x3v9
- Warn: Project is vulnerable to: GHSA-hrpp-h998-j3pp
- Warn: Project is vulnerable to: GHSA-p8p7-x288-28g6
- Warn: Project is vulnerable to: GHSA-gcx4-mw62-g8wm
- Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw
- Warn: Project is vulnerable to: GHSA-h9rv-jmmf-4pgx
- Warn: Project is vulnerable to: GHSA-hxcc-f52p-wc94
- Warn: Project is vulnerable to: GHSA-3jfq-g458-7qm9
- Warn: Project is vulnerable to: GHSA-r628-mhmh-qjhw
- Warn: Project is vulnerable to: GHSA-9r2w-394v-53qc
- Warn: Project is vulnerable to: GHSA-5955-9wpr-37jh
- Warn: Project is vulnerable to: GHSA-qq89-hq3f-393p
- Warn: Project is vulnerable to: GHSA-f5x3-32g6-xq36
- Warn: Project is vulnerable to: GHSA-4wf5-vphf-c2xc
- Warn: Project is vulnerable to: GHSA-jgrx-mgxx-jf9v
- Warn: Project is vulnerable to: GHSA-72xf-g2v4-qvf3
- Warn: Project is vulnerable to: GHSA-6fc8-4gx4-v693
- Warn: Project is vulnerable to: GHSA-3h5v-q93c-6h6q
- Warn: Project is vulnerable to: GHSA-c4w7-xm78-47vh
Score
1.7
/10
Last Scanned on 2025-01-27
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More