rxtutils 1.1.4-beta.15 → 1.1.4-beta.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/cache/index.cjs +48 -66
- package/cjs/cache/index.d.ts +1 -1
- package/cjs/cache/indexDB.cjs +36 -43
- package/cjs/hooks/useCombineControlValue.cjs +9 -14
- package/cjs/request/defaultHandlers.cjs +3 -3
- package/cjs/request/error.cjs +7 -12
- package/cjs/request/index.cjs +145 -160
- package/cjs/request/index.d.ts +14 -0
- package/cjs/store/createGetter/index.cjs +11 -11
- package/cjs/store/createStateStore/index.cjs +22 -22
- package/cjs/validator/decorators.cjs +44 -55
- package/cjs/validator/validator.cjs +83 -93
- package/es/cache/index.d.ts +1 -1
- package/es/cache/index.mjs +48 -66
- package/es/cache/indexDB.mjs +36 -43
- package/es/hooks/useCombineControlValue.mjs +9 -14
- package/es/request/defaultHandlers.mjs +3 -3
- package/es/request/error.mjs +7 -12
- package/es/request/index.d.ts +14 -0
- package/es/request/index.mjs +145 -160
- package/es/store/createGetter/index.mjs +11 -11
- package/es/store/createStateStore/index.mjs +22 -22
- package/es/validator/decorators.mjs +44 -55
- package/es/validator/validator.mjs +83 -93
- package/package.json +7 -2
package/cjs/request/index.cjs
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var tslib = require('tslib');
|
|
4
3
|
var axios = require('axios');
|
|
5
4
|
var at = require('lodash-es/at');
|
|
6
5
|
var defaultHandlers = require('./defaultHandlers.cjs');
|
|
@@ -14,11 +13,10 @@ var error = require('./error.cjs');
|
|
|
14
13
|
* @returns 请求创建函数
|
|
15
14
|
*/
|
|
16
15
|
function createBaseRequest(baseOptions) {
|
|
17
|
-
|
|
18
|
-
// 创建新的 Axios 实例并配置基础URL
|
|
19
|
-
|
|
16
|
+
const { baseURL } = Object(baseOptions);
|
|
17
|
+
// 创建新的 Axios 实例并配置基础URL
|
|
18
|
+
const instance = axios.create({
|
|
20
19
|
baseURL: baseURL,
|
|
21
|
-
withCredentials: true,
|
|
22
20
|
});
|
|
23
21
|
/**
|
|
24
22
|
* 创建请求函数
|
|
@@ -29,166 +27,153 @@ function createBaseRequest(baseOptions) {
|
|
|
29
27
|
* @returns 发送请求的函数
|
|
30
28
|
*/
|
|
31
29
|
return function createRequest(requestOptions, createOptions) {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
30
|
+
const { method, url } = { ...requestOptions };
|
|
31
|
+
const { baseURL, cacheDataKey = `${method}:${baseURL}${url}`, cacheDataInStorage, cacheKeyEquals = defaultEquals, cacheTime, indexDBName = "__apiCacheDatabase__", } = {
|
|
32
|
+
...baseOptions,
|
|
33
|
+
...createOptions,
|
|
34
|
+
};
|
|
35
|
+
const cache = new index.default(cacheDataInStorage, cacheDataKey, cacheTime, indexDBName, cacheKeyEquals);
|
|
36
|
+
async function request(requestParam, options) {
|
|
37
|
+
const mergedOptions = {
|
|
38
|
+
...baseOptions,
|
|
39
|
+
...createOptions,
|
|
40
|
+
...options,
|
|
41
|
+
};
|
|
42
|
+
let { requestMiddlewares = [], axiosOptions: finalAxiosOptions = {}, requestParamsOrDataTransfer, responseTransfer } = mergedOptions;
|
|
43
|
+
let finalRequestOptions = { ...requestOptions, ...requestParam };
|
|
44
|
+
for (const middleware of requestMiddlewares) {
|
|
45
|
+
const { axiosOptions: nextAxiosOptions = finalAxiosOptions, requestOptions: nextRequestOptions = finalRequestOptions } = await middleware({ ...mergedOptions, axiosOptions: finalAxiosOptions }, finalRequestOptions);
|
|
46
|
+
finalAxiosOptions = nextAxiosOptions;
|
|
47
|
+
finalRequestOptions = nextRequestOptions;
|
|
48
|
+
}
|
|
49
|
+
const { method, url, data = {}, params = {}, } = finalRequestOptions;
|
|
50
|
+
let requestDataOrParams = params;
|
|
51
|
+
if (method.toLowerCase() === "post") {
|
|
52
|
+
requestDataOrParams = data;
|
|
53
|
+
}
|
|
54
|
+
const { defaultMessageShower = console.error } = {
|
|
55
|
+
...baseOptions,
|
|
56
|
+
...createOptions,
|
|
57
|
+
...options,
|
|
58
|
+
};
|
|
59
|
+
const { enableCache = false, cacheData = false, defaultErrorCodeHandler = defaultHandlers._defaultErrorCodeHandler.bind(null, defaultMessageShower), defaultHttpErrorCodeHandler = defaultHandlers._defaultHttpErrorCodeHandler.bind(null, defaultMessageShower), otherErrorHandler = defaultHandlers._defaultOtherErrorCodeHandler.bind(null, defaultMessageShower), errorCodePath = "code", cacheTime = 60, errorCodeMap = {}, successCodes = ["0", "200"], httpErrorCodeMap = {},
|
|
60
|
+
// axiosOptions = {},
|
|
61
|
+
throwError = true, retryTimes = 0 } = { ...baseOptions, ...createOptions, ...options };
|
|
62
|
+
if (enableCache) {
|
|
63
|
+
const cacheItem = cache.getCache(requestDataOrParams);
|
|
64
|
+
if (cacheItem) {
|
|
65
|
+
return Promise.resolve(cacheItem);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function retry() {
|
|
69
|
+
if (retryTimes > 0) {
|
|
70
|
+
return request(requestParam, { ...options, retryTimes: retryTimes - 1 });
|
|
71
|
+
}
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
return instance
|
|
75
|
+
.request({
|
|
76
|
+
method,
|
|
77
|
+
url,
|
|
78
|
+
data: data ?? (requestParamsOrDataTransfer ? requestParamsOrDataTransfer(data) : data),
|
|
79
|
+
params: params ?? (requestParamsOrDataTransfer ? requestParamsOrDataTransfer(params) : params),
|
|
80
|
+
...finalAxiosOptions,
|
|
81
|
+
})
|
|
82
|
+
.then(async (res) => {
|
|
83
|
+
const errorCode = String(at(res.data, errorCodePath));
|
|
84
|
+
let finalData = responseTransfer ? responseTransfer(res.data) : res.data;
|
|
85
|
+
if (successCodes.includes(errorCode)) {
|
|
86
|
+
if (cacheData) {
|
|
87
|
+
cache.setCache(requestDataOrParams, finalData, { cacheTime });
|
|
40
88
|
}
|
|
41
|
-
return
|
|
89
|
+
return finalData;
|
|
90
|
+
}
|
|
91
|
+
// 不在成功 code 中,意味着请求失败
|
|
92
|
+
const { [errorCode]: customHandler = defaultErrorCodeHandler } = errorCodeMap;
|
|
93
|
+
const err = new error("服务端错误", "server", res);
|
|
94
|
+
if (typeof customHandler === "string") {
|
|
95
|
+
defaultMessageShower(customHandler);
|
|
96
|
+
const retryTask = retry();
|
|
97
|
+
if (retryTask)
|
|
98
|
+
return retryTask;
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
const { replaceResData = res.data, throwError: handlerThrowError = "default", } = Object((await customHandler(errorCode, res.data, res, {
|
|
102
|
+
...requestOptions,
|
|
103
|
+
...requestParam,
|
|
104
|
+
})));
|
|
105
|
+
const retryTask = retry();
|
|
106
|
+
if (retryTask)
|
|
107
|
+
return retryTask;
|
|
108
|
+
res.data = replaceResData;
|
|
109
|
+
switch (handlerThrowError) {
|
|
110
|
+
case true:
|
|
111
|
+
throw err;
|
|
112
|
+
case false:
|
|
113
|
+
return res.data;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
if (throwError) {
|
|
117
|
+
throw err;
|
|
42
118
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
if (!(_i < requestMiddlewares_1.length)) return [3 /*break*/, 4];
|
|
56
|
-
middleware = requestMiddlewares_1[_i];
|
|
57
|
-
return [4 /*yield*/, middleware(finalAxiosOptions, finalRequestOptions)];
|
|
58
|
-
case 2:
|
|
59
|
-
_d = _y.sent(), _e = _d.axiosOptions, nextAxiosOptions = _e === void 0 ? finalAxiosOptions : _e, _f = _d.requestOptions, nextRequestOptions = _f === void 0 ? finalRequestOptions : _f;
|
|
60
|
-
finalAxiosOptions = nextAxiosOptions;
|
|
61
|
-
finalRequestOptions = nextRequestOptions;
|
|
62
|
-
_y.label = 3;
|
|
63
|
-
case 3:
|
|
64
|
-
_i++;
|
|
65
|
-
return [3 /*break*/, 1];
|
|
66
|
-
case 4:
|
|
67
|
-
method = finalRequestOptions.method, url = finalRequestOptions.url, _g = finalRequestOptions.data, data = _g === void 0 ? {} : _g, _h = finalRequestOptions.params, params = _h === void 0 ? {} : _h;
|
|
68
|
-
requestDataOrParams = params;
|
|
69
|
-
if (method.toLowerCase() === "post") {
|
|
70
|
-
requestDataOrParams = data;
|
|
71
|
-
}
|
|
72
|
-
_j = tslib.__assign(tslib.__assign(tslib.__assign({}, baseOptions), createOptions), options).defaultMessageShower, defaultMessageShower = _j === void 0 ? console.error : _j;
|
|
73
|
-
_k = tslib.__assign(tslib.__assign(tslib.__assign({}, baseOptions), createOptions), options), _l = _k.enableCache, enableCache = _l === void 0 ? false : _l, _m = _k.cacheData, cacheData = _m === void 0 ? false : _m, _o = _k.defaultErrorCodeHandler, defaultErrorCodeHandler = _o === void 0 ? defaultHandlers._defaultErrorCodeHandler.bind(null, defaultMessageShower) : _o, _p = _k.defaultHttpErrorCodeHandler, defaultHttpErrorCodeHandler = _p === void 0 ? defaultHandlers._defaultHttpErrorCodeHandler.bind(null, defaultMessageShower) : _p, _q = _k.otherErrorHandler, otherErrorHandler = _q === void 0 ? defaultHandlers._defaultOtherErrorCodeHandler.bind(null, defaultMessageShower) : _q, _r = _k.errorCodePath, errorCodePath = _r === void 0 ? "code" : _r, _s = _k.cacheTime, cacheTime = _s === void 0 ? 60 : _s, _t = _k.errorCodeMap, errorCodeMap = _t === void 0 ? {} : _t, _u = _k.successCodes, successCodes = _u === void 0 ? ["0", "200"] : _u, _v = _k.httpErrorCodeMap, httpErrorCodeMap = _v === void 0 ? {} : _v, _w = _k.throwError, throwError = _w === void 0 ? true : _w, _x = _k.retryTimes, retryTimes = _x === void 0 ? 0 : _x;
|
|
74
|
-
if (enableCache) {
|
|
75
|
-
cacheItem = cache.getCache(requestDataOrParams);
|
|
76
|
-
if (cacheItem) {
|
|
77
|
-
return [2 /*return*/, Promise.resolve(cacheItem)];
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
return [2 /*return*/, instance
|
|
81
|
-
.request(tslib.__assign({ method: method, url: url, data: data, params: params }, finalAxiosOptions))
|
|
82
|
-
.then(function (res) { return tslib.__awaiter(_this, void 0, void 0, function () {
|
|
83
|
-
var errorCode, _a, _b, _c, customHandler, err, retryTask, _d, _e, replaceResData, _f, handlerThrowError, _g, retryTask;
|
|
84
|
-
return tslib.__generator(this, function (_h) {
|
|
85
|
-
switch (_h.label) {
|
|
86
|
-
case 0:
|
|
87
|
-
errorCode = String(at(res.data, errorCodePath));
|
|
88
|
-
if (successCodes.includes(errorCode)) {
|
|
89
|
-
if (cacheData) {
|
|
90
|
-
cache.setCache(requestDataOrParams, res.data, { cacheTime: cacheTime });
|
|
91
|
-
}
|
|
92
|
-
return [2 /*return*/, res.data];
|
|
93
|
-
}
|
|
94
|
-
_a = errorCodeMap, _b = errorCode, _c = _a[_b], customHandler = _c === void 0 ? defaultErrorCodeHandler : _c;
|
|
95
|
-
err = new error("服务端错误", "server", res);
|
|
96
|
-
if (!(typeof customHandler === "string")) return [3 /*break*/, 1];
|
|
97
|
-
defaultMessageShower(customHandler);
|
|
98
|
-
retryTask = retry();
|
|
99
|
-
if (retryTask)
|
|
100
|
-
return [2 /*return*/, retryTask];
|
|
101
|
-
return [3 /*break*/, 3];
|
|
102
|
-
case 1:
|
|
103
|
-
_g = Object;
|
|
104
|
-
return [4 /*yield*/, customHandler(errorCode, res.data, res, tslib.__assign(tslib.__assign({}, requestOptions), requestParam))];
|
|
105
|
-
case 2:
|
|
106
|
-
_d = _g.apply(void 0, [(_h.sent())]), _e = _d.replaceResData, replaceResData = _e === void 0 ? res.data : _e, _f = _d.throwError, handlerThrowError = _f === void 0 ? "default" : _f;
|
|
107
|
-
retryTask = retry();
|
|
108
|
-
if (retryTask)
|
|
109
|
-
return [2 /*return*/, retryTask];
|
|
110
|
-
res.data = replaceResData;
|
|
111
|
-
switch (handlerThrowError) {
|
|
112
|
-
case true:
|
|
113
|
-
throw err;
|
|
114
|
-
case false:
|
|
115
|
-
return [2 /*return*/, res.data];
|
|
116
|
-
}
|
|
117
|
-
_h.label = 3;
|
|
118
|
-
case 3:
|
|
119
|
-
if (throwError) {
|
|
120
|
-
throw err;
|
|
121
|
-
}
|
|
122
|
-
return [2 /*return*/, res.data];
|
|
123
|
-
}
|
|
124
|
-
});
|
|
125
|
-
}); }, function (error$1) { return tslib.__awaiter(_this, void 0, void 0, function () {
|
|
126
|
-
var resData, _a, _b, _c, customHandler, err, retryTask, _d, _e, replaceResData, _f, handlerThrowError, _g, retryTask, resData, err, _h, _j, replaceResData, _k, handlerThrowError, _l, retryTask;
|
|
127
|
-
return tslib.__generator(this, function (_m) {
|
|
128
|
-
switch (_m.label) {
|
|
129
|
-
case 0:
|
|
130
|
-
if (!error$1.response) return [3 /*break*/, 4];
|
|
131
|
-
resData = error$1;
|
|
132
|
-
_a = httpErrorCodeMap, _b = error$1.response.status, _c = _a[_b], customHandler = _c === void 0 ? defaultHttpErrorCodeHandler : _c;
|
|
133
|
-
err = new error("服务端错误", "http", error$1);
|
|
134
|
-
if (!(typeof customHandler === "string")) return [3 /*break*/, 1];
|
|
135
|
-
defaultMessageShower(customHandler);
|
|
136
|
-
retryTask = retry();
|
|
137
|
-
if (retryTask)
|
|
138
|
-
return [2 /*return*/, retryTask];
|
|
139
|
-
return [3 /*break*/, 3];
|
|
140
|
-
case 1:
|
|
141
|
-
_g = Object;
|
|
142
|
-
return [4 /*yield*/, customHandler(error$1.response.status, error$1, tslib.__assign(tslib.__assign({}, requestOptions), requestParam))];
|
|
143
|
-
case 2:
|
|
144
|
-
_d = _g.apply(void 0, [(_m.sent())]), _e = _d.replaceResData, replaceResData = _e === void 0 ? error$1 : _e, _f = _d.throwError, handlerThrowError = _f === void 0 ? "default" : _f;
|
|
145
|
-
retryTask = retry();
|
|
146
|
-
if (retryTask)
|
|
147
|
-
return [2 /*return*/, retryTask];
|
|
148
|
-
resData = replaceResData;
|
|
149
|
-
switch (handlerThrowError) {
|
|
150
|
-
case true:
|
|
151
|
-
throw err;
|
|
152
|
-
case false:
|
|
153
|
-
return [2 /*return*/, resData];
|
|
154
|
-
}
|
|
155
|
-
_m.label = 3;
|
|
156
|
-
case 3:
|
|
157
|
-
if (throwError) {
|
|
158
|
-
throw err;
|
|
159
|
-
}
|
|
160
|
-
return [2 /*return*/, resData];
|
|
161
|
-
case 4:
|
|
162
|
-
resData = error$1;
|
|
163
|
-
err = new error("服务端错误", "http", error$1);
|
|
164
|
-
err.type = "http";
|
|
165
|
-
err.data = error$1;
|
|
166
|
-
_l = Object;
|
|
167
|
-
return [4 /*yield*/, otherErrorHandler(error$1)];
|
|
168
|
-
case 5:
|
|
169
|
-
_h = (_l.apply(void 0, [(_m.sent())])), _j = _h.replaceResData, replaceResData = _j === void 0 ? error$1 : _j, _k = _h.throwError, handlerThrowError = _k === void 0 ? "default" : _k;
|
|
170
|
-
retryTask = retry();
|
|
171
|
-
if (retryTask)
|
|
172
|
-
return [2 /*return*/, retryTask];
|
|
173
|
-
resData = replaceResData;
|
|
174
|
-
switch (handlerThrowError) {
|
|
175
|
-
case true:
|
|
176
|
-
throw err;
|
|
177
|
-
case false:
|
|
178
|
-
return [2 /*return*/, resData];
|
|
179
|
-
}
|
|
180
|
-
if (throwError) {
|
|
181
|
-
throw err;
|
|
182
|
-
}
|
|
183
|
-
return [2 /*return*/, resData];
|
|
184
|
-
}
|
|
185
|
-
});
|
|
186
|
-
}); })];
|
|
119
|
+
return res.data;
|
|
120
|
+
}, async (error$1) => {
|
|
121
|
+
if (error$1.response) {
|
|
122
|
+
// 请求成功发出且服务器也响应了状态码,但状态代码超出了 2xx 的范围
|
|
123
|
+
let resData = error$1;
|
|
124
|
+
const { [error$1.response.status]: customHandler = defaultHttpErrorCodeHandler, } = httpErrorCodeMap;
|
|
125
|
+
const err = new error("服务端错误", "http", error$1);
|
|
126
|
+
if (typeof customHandler === "string") {
|
|
127
|
+
defaultMessageShower(customHandler);
|
|
128
|
+
const retryTask = retry();
|
|
129
|
+
if (retryTask)
|
|
130
|
+
return retryTask;
|
|
187
131
|
}
|
|
188
|
-
|
|
132
|
+
else {
|
|
133
|
+
const { replaceResData = error$1, throwError: handlerThrowError = "default", } = Object((await customHandler(error$1.response.status, error$1, {
|
|
134
|
+
...requestOptions,
|
|
135
|
+
...requestParam,
|
|
136
|
+
})));
|
|
137
|
+
const retryTask = retry();
|
|
138
|
+
if (retryTask)
|
|
139
|
+
return retryTask;
|
|
140
|
+
resData = replaceResData;
|
|
141
|
+
switch (handlerThrowError) {
|
|
142
|
+
case true:
|
|
143
|
+
throw err;
|
|
144
|
+
case false:
|
|
145
|
+
return resData;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
if (throwError) {
|
|
149
|
+
throw err;
|
|
150
|
+
}
|
|
151
|
+
return resData;
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
let resData = error$1;
|
|
155
|
+
const err = new error("服务端错误", "http", error$1);
|
|
156
|
+
err.type = "http";
|
|
157
|
+
err.data = error$1;
|
|
158
|
+
const { replaceResData = error$1, throwError: handlerThrowError = "default", } = (Object((await otherErrorHandler(error$1))));
|
|
159
|
+
const retryTask = retry();
|
|
160
|
+
if (retryTask)
|
|
161
|
+
return retryTask;
|
|
162
|
+
resData = replaceResData;
|
|
163
|
+
switch (handlerThrowError) {
|
|
164
|
+
case true:
|
|
165
|
+
throw err;
|
|
166
|
+
case false:
|
|
167
|
+
return resData;
|
|
168
|
+
}
|
|
169
|
+
if (throwError) {
|
|
170
|
+
throw err;
|
|
171
|
+
}
|
|
172
|
+
return resData;
|
|
173
|
+
}
|
|
189
174
|
});
|
|
190
175
|
}
|
|
191
|
-
request.clearCache =
|
|
176
|
+
request.clearCache = () => {
|
|
192
177
|
cache.clear();
|
|
193
178
|
};
|
|
194
179
|
return request;
|
package/cjs/request/index.d.ts
CHANGED
|
@@ -119,6 +119,20 @@ interface Options<Params = any, Data = any> {
|
|
|
119
119
|
requestOptions?: RequestOptions<Params>;
|
|
120
120
|
})[];
|
|
121
121
|
retryTimes?: number;
|
|
122
|
+
/**
|
|
123
|
+
* 请求参数或数据转换函数
|
|
124
|
+
* 可以在发送请求前对参数或数据进行处理
|
|
125
|
+
* @param paramsOrData 请求参数或数据
|
|
126
|
+
* @returns 处理后的参数或数据
|
|
127
|
+
*/
|
|
128
|
+
requestParamsOrDataTransfer?: (paramsOrData: Params) => any;
|
|
129
|
+
/**
|
|
130
|
+
* 响应数据转换函数
|
|
131
|
+
* 可以在接收响应数据后对数据进行处理
|
|
132
|
+
* @param data 响应数据
|
|
133
|
+
* @returns 处理后的响应数据
|
|
134
|
+
*/
|
|
135
|
+
responseTransfer?: (data: any) => Data;
|
|
122
136
|
}
|
|
123
137
|
/**
|
|
124
138
|
* 请求参数接口
|
|
@@ -9,11 +9,11 @@ var react = require('react');
|
|
|
9
9
|
* @param getterNameMaps 将 getter 函数和 getter 名称一一映射
|
|
10
10
|
* @returns getter object
|
|
11
11
|
*/
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
Object.keys(getters).forEach(
|
|
12
|
+
const createStoreGetter = (store, getters, getterNameMaps) => {
|
|
13
|
+
const gettersObj = {};
|
|
14
|
+
Object.keys(getters).forEach((key) => {
|
|
15
15
|
Object.defineProperty(gettersObj, getterNameMaps[key], {
|
|
16
|
-
get:
|
|
16
|
+
get: () => getters[key](store.get())
|
|
17
17
|
});
|
|
18
18
|
});
|
|
19
19
|
return gettersObj;
|
|
@@ -25,14 +25,14 @@ var createStoreGetter = function (store, getters, getterNameMaps) {
|
|
|
25
25
|
* @param getterNameMaps 将 getter 函数和 getter 名称一一映射
|
|
26
26
|
* @returns getter memo hook
|
|
27
27
|
*/
|
|
28
|
-
|
|
28
|
+
const createStoreGetterMemo = (store, getters, getterNameMaps) => {
|
|
29
29
|
// 创建缓存数据 hook
|
|
30
|
-
return
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
return Object.keys(getters).reduce(
|
|
34
|
-
|
|
35
|
-
|
|
30
|
+
return () => {
|
|
31
|
+
const [storeData] = store.use();
|
|
32
|
+
const reducedData = react.useMemo(() => {
|
|
33
|
+
return Object.keys(getters).reduce((acc, key) => {
|
|
34
|
+
const mappedKey = getterNameMaps[key];
|
|
35
|
+
const getterValue = getters[key](storeData);
|
|
36
36
|
acc[mappedKey] = getterValue;
|
|
37
37
|
return acc;
|
|
38
38
|
}, {});
|
|
@@ -13,19 +13,19 @@ function resolveHookState(nextState, currentState) {
|
|
|
13
13
|
return nextState;
|
|
14
14
|
}
|
|
15
15
|
/** 判断当前环境是否为浏览器 */
|
|
16
|
-
|
|
16
|
+
const isBrowser = typeof window !== 'undefined';
|
|
17
17
|
/**
|
|
18
18
|
* 只执行一次的 useEffect hook
|
|
19
19
|
* @param effect 要执行的副作用函数
|
|
20
20
|
*/
|
|
21
|
-
|
|
21
|
+
const useEffectOnce = (effect) => {
|
|
22
22
|
react.useEffect(effect, []);
|
|
23
23
|
};
|
|
24
24
|
/**
|
|
25
25
|
* 同构的 useLayoutEffect
|
|
26
26
|
* 在服务端渲染时使用 useEffect,在浏览器环境使用 useLayoutEffect
|
|
27
27
|
*/
|
|
28
|
-
|
|
28
|
+
const useIsomorphicLayoutEffect = isBrowser ? react.useLayoutEffect : react.useEffect;
|
|
29
29
|
/**
|
|
30
30
|
* 创建状态存储
|
|
31
31
|
* 提供一个简单的状态管理解决方案,支持组件间状态共享
|
|
@@ -39,12 +39,12 @@ function createStateStore(initialState) {
|
|
|
39
39
|
* 状态存储对象
|
|
40
40
|
* 包含当前状态、设置状态的方法、状态更新器和监听器列表
|
|
41
41
|
*/
|
|
42
|
-
|
|
42
|
+
const store = {
|
|
43
43
|
state: initialState instanceof Function ? initialState() : initialState,
|
|
44
|
-
setState
|
|
44
|
+
setState(nextState) {
|
|
45
45
|
store.state = resolveHookState(nextState, store.state);
|
|
46
|
-
store.setters.forEach(
|
|
47
|
-
store.watchers.forEach(
|
|
46
|
+
store.setters.forEach((setter) => setter(store.state));
|
|
47
|
+
store.watchers.forEach((watcher) => watcher(store.state));
|
|
48
48
|
},
|
|
49
49
|
setters: [],
|
|
50
50
|
watchers: [],
|
|
@@ -55,15 +55,15 @@ function createStateStore(initialState) {
|
|
|
55
55
|
*
|
|
56
56
|
* @returns [当前状态, 状态更新函数]
|
|
57
57
|
*/
|
|
58
|
-
|
|
58
|
+
const use = () => {
|
|
59
59
|
// 使用 React 的 useState 创建组件本地状态
|
|
60
|
-
|
|
60
|
+
const [globalState, stateSetter] = react.useState(store.state);
|
|
61
61
|
// 组件卸载时清理状态更新器
|
|
62
|
-
useEffectOnce(
|
|
63
|
-
store.setters = store.setters.filter(
|
|
64
|
-
}
|
|
62
|
+
useEffectOnce(() => () => {
|
|
63
|
+
store.setters = store.setters.filter((setter) => setter !== stateSetter);
|
|
64
|
+
});
|
|
65
65
|
// 在组件挂载和更新时注册状态更新器
|
|
66
|
-
useIsomorphicLayoutEffect(
|
|
66
|
+
useIsomorphicLayoutEffect(() => {
|
|
67
67
|
if (!store.setters.includes(stateSetter)) {
|
|
68
68
|
store.setters.push(stateSetter);
|
|
69
69
|
}
|
|
@@ -71,26 +71,26 @@ function createStateStore(initialState) {
|
|
|
71
71
|
return [globalState, store.setState];
|
|
72
72
|
};
|
|
73
73
|
/** 获取当前状态值 */
|
|
74
|
-
|
|
74
|
+
const get = () => store.state;
|
|
75
75
|
/** 设置状态的函数引用 */
|
|
76
|
-
|
|
76
|
+
const set = store.setState;
|
|
77
77
|
/**
|
|
78
78
|
* 监听状态变化
|
|
79
79
|
* @param callback 状态变化时的回调函数
|
|
80
80
|
* @returns 取消监听的函数
|
|
81
81
|
*/
|
|
82
|
-
|
|
82
|
+
const watch = (callback) => {
|
|
83
83
|
store.watchers.push(callback);
|
|
84
|
-
|
|
85
|
-
store.watchers = store.watchers.filter(
|
|
84
|
+
const close = () => {
|
|
85
|
+
store.watchers = store.watchers.filter((watcher) => watcher !== callback);
|
|
86
86
|
};
|
|
87
87
|
return close;
|
|
88
88
|
};
|
|
89
89
|
return {
|
|
90
|
-
use
|
|
91
|
-
get
|
|
92
|
-
set
|
|
93
|
-
watch
|
|
90
|
+
use,
|
|
91
|
+
get,
|
|
92
|
+
set,
|
|
93
|
+
watch,
|
|
94
94
|
};
|
|
95
95
|
}
|
|
96
96
|
|