1
- import { useState , useMemo } from 'react'
1
+ import { useState , useMemo , useEffect } from 'react'
2
2
3
- import type { UseListOptions , UseListState , LoadOptions , LoadArgs } from './types'
3
+ import type { UseListState , UseListOptions , List , UseListInstance , ListFetchOptions , ListFetchArgs } from './types'
4
4
5
5
/**
6
6
* 列表 hook 函数
@@ -23,23 +23,23 @@ import type { UseListOptions, UseListState, LoadOptions, LoadArgs } from './type
23
23
*
24
24
* @return 返回列表状态与方法
25
25
*/
26
- export function useList < T > ( options : UseListOptions < T > ) {
27
- const dispatchRequest = options . dispatchRequest
26
+ export function useList < T > ( options : UseListOptions < T > ) : UseListInstance < T > {
27
+ const onFetch = options . onFetch
28
28
29
+ // 列表变更模式
29
30
const mode = options . mode || 'replace'
30
31
32
+ // 加载状态
33
+ const loading = options . loading === true
34
+
35
+ // 列表状态
31
36
const [ state , setState ] = useState < UseListState < T > > ( {
32
37
items : options . items ?? [ ] ,
33
38
page : options . page || 1 ,
34
39
pageSize : options . pageSize || 10 ,
35
40
total : options . total || 0 ,
36
41
} )
37
42
38
- /**
39
- * 加载状态
40
- */
41
- const loading = useMemo < boolean > ( ( ) => options . loading === true , [ options . loading ] )
42
-
43
43
/**
44
44
* 是否第一页
45
45
*/
@@ -53,20 +53,30 @@ export function useList<T>(options: UseListOptions<T>) {
53
53
state . total ,
54
54
] )
55
55
56
- function refresh ( options ?: LoadOptions ) {
57
- return load ( { } , { ...options , refresh : true } )
56
+ /**
57
+ * 刷新列表
58
+ *
59
+ * @param options 刷新配置
60
+ */
61
+ function refresh ( options ?: ListFetchOptions ) {
62
+ return dispatchRequest ( { } , { ...options , refresh : true } )
58
63
}
59
64
60
- function search ( args ?: Partial < LoadArgs > ) {
65
+ /**
66
+ * 搜索方法
67
+ *
68
+ * @param args 搜索参数
69
+ */
70
+ function search ( args ?: Partial < ListFetchArgs > ) {
61
71
// 默认,搜索就跳转回第一页
62
- return load ( { page : 1 , ...args } , { force : true } )
72
+ return dispatchRequest ( { page : 1 , ...args } , { force : true } )
63
73
}
64
74
65
75
function clear ( ) {
66
76
setState ( { items : [ ] , page : 1 , pageSize : 10 , total : 0 } )
67
77
}
68
78
69
- async function load ( args ?: Partial < LoadArgs > , options ?: LoadOptions ) {
79
+ async function dispatchRequest ( args ?: Partial < ListFetchArgs > , options ?: ListFetchOptions ) {
70
80
args = args || { }
71
81
options = options || { }
72
82
@@ -77,21 +87,28 @@ export function useList<T>(options: UseListOptions<T>) {
77
87
if ( options . force !== true ) return Promise . resolve ( )
78
88
}
79
89
80
- const res = await dispatchRequest ( { page, pageSize } , { ...options , state, mode } )
90
+ const res = await onFetch ( { page, pageSize } , { ...options , state, mode } )
81
91
if ( ! res ) return
82
92
83
93
let items : T [ ] = [ ]
84
94
if ( mode === 'manual' || options . refresh === true ) {
85
- items = res . items
95
+ items = res . items || [ ]
86
96
} else {
87
- items = mode === 'append' ? state . items . concat ( res . items ) : res . items
97
+ items = mode === 'append' ? state . items . concat ( res . items || [ ] ) : res . items || [ ]
88
98
}
89
99
90
- setState ( { items, page, pageSize, total : res . total } )
100
+ setState ( { items, page : res . page || page , pageSize : res . pageSize || pageSize , total : res . total || 0 } )
91
101
}
92
102
93
- function loadPageData ( page : number , options ?: LoadOptions ) {
94
- return load ( { page } , options )
103
+ /**
104
+ * 加载制定页数据
105
+ *
106
+ * @param page 指定页
107
+ * @param options
108
+ * @param options.force 是否强制刷新
109
+ */
110
+ function loadPageData ( page : number , options ?: ListFetchOptions ) {
111
+ return dispatchRequest ( { page } , options )
95
112
}
96
113
97
114
/**
@@ -100,7 +117,7 @@ export function useList<T>(options: UseListOptions<T>) {
100
117
* @param options
101
118
* @param options.force 是否强制刷新
102
119
*/
103
- function loadPreviousPageData ( options ?: LoadOptions ) {
120
+ function loadPreviousPageData ( options ?: ListFetchOptions ) {
104
121
return isFirst ? Promise . resolve ( ) : loadPageData ( state . page - 1 , options )
105
122
}
106
123
@@ -110,15 +127,25 @@ export function useList<T>(options: UseListOptions<T>) {
110
127
* @param options 可选项
111
128
* @param options.force 是否强制刷新
112
129
*/
113
- function loadNextPageData ( options ?: LoadOptions ) {
130
+ function loadNextPageData ( options ?: ListFetchOptions ) {
114
131
return isEnd ? Promise . resolve ( ) : loadPageData ( state . page + 1 , options )
115
132
}
116
133
134
+ /** 数据转换 */
135
+ function toJSON ( ) : List < T > {
136
+ return state
137
+ }
138
+
139
+ useEffect ( ( ) => {
140
+ // 自动加载
141
+ if ( options . autoLoad === true ) refresh ( )
142
+ } , [ ] )
143
+
117
144
return {
145
+ // state
118
146
...state ,
119
147
120
148
// computed
121
- loading,
122
149
isFirst,
123
150
isEnd,
124
151
@@ -132,5 +159,6 @@ export function useList<T>(options: UseListOptions<T>) {
132
159
133
160
// sync methods
134
161
clear,
162
+ toJSON,
135
163
}
136
164
}
0 commit comments