10
10
11
11
reducer可以持续有效的管理数据变更,让数据处理模式变的井井有条,所以react开发了userReducer hook工具,但reducer也有自己的一些麻烦事。
12
12
为了让reducer变得更容易使用,这里引入了 [ agent-reducer] ( https://www.npmjs.com/package/agent-reducer ) 工具,
13
- 以便使用者可以利用class方法调用的形式来完成一个reducer的工作,该工具结合了reducer的return即修改的特性 ,
13
+ 以便使用者可以利用class方法调用的形式来完成一个reducer的工作,该工具结合了reducer的return即为下一个state的特性 ,
14
14
同时又使用更自然的方法调用代替了reducer复杂的dispatch系统,算的上是函数式编程和面向对象编程模式的完美结合了。
15
15
16
- 该工具可以用来作为react中类似 MVVM 设计的框架使用,当然因为它的侵入性小,所以把它定义成一个 MVVM 工具更加合理 。
16
+ 该工具可以用来作为react中类似 MVVM 设计的框架使用,当然它的设计初衷是为了替代 useReducer 。
17
17
18
18
### 换种写法
19
19
``` typescript
@@ -68,6 +68,10 @@ import {OriginAgent} from "agent-reducer";
68
68
` return ` 值作为计算完后的` this.state ` 数据(这里并未涉及state维护器,所以先当作有这么一个黑盒工具)。
69
69
有点像reducer,但省去了action的复杂结构(action为了兼容多个分支的不同需求所以很难以普通传参方式来工作)。
70
70
71
+ #### 重要说明
72
+
73
+ 当前版本为3.0.0,关于2.+.+即以下版本的很多方法或改名或不再支持。
74
+
71
75
用` useAgent ` 来代替` useReducer `
72
76
73
77
``` tsx
@@ -108,17 +112,15 @@ export const Counter = memo(() => {
108
112
});
109
113
```
110
114
以上代码是一个简单的例子,` useAgent ` 返回的是一个` CountAgent ` 实例代理对象。
111
- 通过调用这个实例代理对象的属性方法就可以 ` dispatch ` 一个` action ` 了,
115
+ 通过调用这个实例代理对象的属性方法就相当于使用 ` reducer ` 工具 ` dispatch ` 一个` action ` 了,
112
116
当` dispatch ` 完成后,` this.state ` 就变成调用方法` return ` 的数据(但并非所有` return ` 数据都会成为下一个` this.state ` )。
113
117
114
- 关于 ` reduce-action ` 和 ` middle-action ` 的定义 ,使用者可以查看 [ agent-reducer] ( https://www.npmjs.com/package/agent-reducer )
118
+ 关于一些基本概念 ,使用者可以查看 [ agent-reducer] ( https://www.npmjs.com/package/agent-reducer )
115
119
116
- 这里做个简单说明,受` agent-reducer ` 使用的默认` MiddleWare ` 影响,
117
- agent属性方法的返回值如果是` undefined ` 或` promise ` ,该方法自身就不会` dispatch ` 任何` action ` 。
118
- 这些方法通常需要调用能够` dispatch action ` 的其他属性方法来修改` this.state ` 。如下:
120
+ 关于异步请求返回值等特殊返回数据,如果希望在二次加工后` dispatch ` 出去,需要使用` MiddleWare ` 。如下:
119
121
``` tsx
120
122
import React ,{memo ,useEffect } from ' react' ;
121
- import {OriginAgent } from " agent-reducer" ;
123
+ import {middleWare , MiddleWarePresets , OriginAgent } from " agent-reducer" ;
122
124
import {useAgent } from ' use-agent-reducer' ;
123
125
124
126
/**
@@ -138,11 +140,12 @@ class CountAgent implements OriginAgent<number> {
138
140
return this .state + counts .reduce ((r , c ): number => r + c , 0 );
139
141
};
140
142
141
- // return promise,所以是 middle-action
142
- // middle-action 本身调用不会触发dispatch,需要调用其他 reduce-action 来修改this.state
143
+ // return promise,如果不加任何MiddleWare再处理,那 state 将会变成一个 promise 对象
144
+ // 使用 MiddleWare 后,promise resolve 值将变成下一个 state
145
+ @middleWare (MiddleWarePresets .takePromiseResolve ())
143
146
async requestAdditions(){
144
147
const args = await Promise .resolve ([1 ,2 ,3 ]);
145
- this .sum (... args );
148
+ return this .sum (... args );
146
149
}
147
150
148
151
}
@@ -165,7 +168,8 @@ export const Counter = memo(() => {
165
168
```
166
169
[ 更多例子] ( https://github.com/filefoxper/use-agent-reducer/blob/master/test/spec/basic.spec.tsx )
167
170
168
- 关于其他 [ agent-reducer] ( https://www.npmjs.com/package/agent-reducer ) 知识,可以进入 ` agent-reducer ` 的readme文件查看获知。
171
+ 关于` MiddleWare ` 的使用,我们推荐` MiddleWarePresets ` ,这省去了` MiddleWare ` 串行的工作,
172
+ 其他 [ agent-reducer] ( https://www.npmjs.com/package/agent-reducer ) 知识,可以进入 ` agent-reducer ` 的readme文件查看获知。
169
173
这是一个比较有意思的工具。
170
174
171
175
### API
@@ -179,93 +183,17 @@ OriginAgent : class | new class();
179
183
180
184
MiddleWare : 见 agent-reducer
181
185
182
- env : {reduceOnly?:boolean, strict?:boolean}
186
+ env : {strict?:boolean}
183
187
184
188
const agent = useAgent(OriginAgent, MiddleWare? | env?, env?);
185
189
```
186
- 关于参数含义可参考: [ agent-reducer ] ( https://www.npmjs.com/package/agent-reducer )
190
+ ` env ` 参数,我们只开放了strict,如果希望在处理之后,渲染之前立即改变 ` this.state ` 可以把它设置为 ` false ` 。
187
191
188
- 2 . useReduceAgent ( >=2.0.0 )
192
+ 关于其他参数含义可参考: [ agent-reducer ] ( https://www.npmjs.com/package/agent-reducer )
189
193
190
- 用来创建一个稳定的agent对象,可用于代替` useState ` 、` useReducer ` 等工具获取更好的MVVM设计体验。
191
- 与 ` useAgent ` 不同的是,` useReduceAgent ` 的` env.reduceOnly ` 必然为` true ` ,
192
- 这意味这` agent ` 模型` class ` 只做` reducer ` 使用,` defaultMiddleWare ` 不再判断返回值是否为` undefined ` 或` promise ` ,
193
- 所有返回数据都将成为` this.state ` ,而且层层代理dispatch也将失效。
194
-
195
- ```
196
- OriginAgent : class | new class();
197
-
198
- MiddleWare : 见 agent-reducer
199
-
200
- env : {strict?:boolean}
201
-
202
- const agent = useReduceAgent(OriginAgent, MiddleWare? | env?, env?);
203
- ```
204
-
205
- 关于参数含义可参考:[ agent-reducer] ( https://www.npmjs.com/package/agent-reducer )
206
-
207
- 如果需要` middle-actions ` ,可以与` useMiddleActions ` 联合使用。如:
208
- ``` tsx
209
- import React ,{memo ,useEffect } from ' react' ;
210
- import {MiddleActions , OriginAgent } from " agent-reducer" ;
211
- import {useReduceAgent ,useMiddleActions } from ' use-agent-reducer' ;
212
-
213
- /**
214
- * class写法
215
- */
216
- class CountAgent implements OriginAgent <number > {
217
-
218
- state = 0 ;
219
-
220
- // 每次调用都让state+1
221
- stepUp = (): number => this .state + 1 ;
222
-
223
- // 每次调用都让state-1
224
- stepDown = (): number => this .state - 1 ;
225
-
226
- step = (isUp : boolean ) => isUp ? this .stepUp () : this .stepDown ();
227
-
228
- sum = (... counts : number []): number => {
229
- return this .state + counts .reduce ((r , c ): number => r + c , 0 );
230
- };
231
-
232
- }
233
-
234
- // 'middle-actions' 可以统一写在一个继承MiddleActions的类里
235
- class CountMiddles extends MiddleActions <CountAgent >{
236
-
237
- async requestAdditions(){
238
- const args = await Promise .resolve ([1 ,2 ,3 ]);
239
- // 该类默认的constructor会把useMiddleActions入参中的agent集成到当前类的agent属性上,以供使用。
240
- this .agent .sum (... args );
241
- }
242
-
243
- }
244
-
245
- export const Counter = memo (() => {
246
-
247
- const agent= useReduceAgent (CountAgent );
248
-
249
- const {state,stepUp,stepDown}= agent ;
250
- // 使用useMiddleActions调用'middle-action'
251
- const {requestAdditions}= useMiddleActions (agent ,CountMiddles );
252
-
253
- useEffect (()=> {
254
- requestAdditions ();
255
- },[]);
256
-
257
- return (
258
- <div >
259
- <button onClick = { stepUp } >stepUp</button >
260
- <span >{ state } </span >
261
- <button onClick = { stepDown } >stepDown</button >
262
- </div >
263
- );
264
- });
265
- ```
266
- 3 . useMiddleActions ( >=2.0.0 )
194
+ 2 . useMiddleActions ( >=2.0.0 3.0.0:接口更改 )
267
195
268
- 配合` useAgent ` 或 ` useReduceAgent ` 使用,可以自定义 ` middle-action ` 集合 ,用于异步请求后` dispatch ` 或做其他任何事情。
196
+ 配合` useAgent ` 使用,用于管理调用 ` agent ` ,用于异步请求后` dispatch ` 或做其他任何事情。
269
197
270
198
```
271
199
class Middles extends MiddleActions<OriginAgent>{
@@ -276,13 +204,14 @@ MiddleWare 见 agent-reducer
276
204
LifecycleMiddleWare 见 agent-reducer
277
205
278
206
const agent=useReduceAgent(OriginAgent);
279
- const middles = useMiddleActions(agent, Middles,MiddleWare? |LifecycleMiddleWare);
207
+ const middles = useMiddleActions(Middles,agent?,...MiddleWare |LifecycleMiddleWare);
280
208
```
281
209
关于参数含义可参考:[ agent-reducer] ( https://www.npmjs.com/package/agent-reducer )
282
210
283
- 4 . useMiddleWare ( >=2.0.0 ) ~~ useBranch ( <2.0.0 ) ~~
211
+ 3 . useMiddleWare ( >=2.0.0 )
284
212
285
- 复制一个` agent ` 成拥有可控生命周期的` agent ` ,有点类似git的分支概念。可通过附加` MiddleWare ` 或` LifecycleMiddleWare ` 控制复制版` agent ` 的特性。
213
+ 复制` agent ` ,获得一个拥有可控生命周期的` agent ` ,有点类似git的分支概念,复制版与原版` agent ` 的非方法属性完全同步。
214
+ 可通过附加` MiddleWare ` 或` LifecycleMiddleWare ` 控制复制版` agent ` 的特性。
286
215
可使用` agent-reducer ` 提供的` LifecycleMiddleWares ` 做到类似` redux-saga ` 的` takeLatest ` 这样的功能。
287
216
288
217
```
@@ -291,7 +220,7 @@ const branch=useMiddleWare(agent, MiddleWare | LifecycleMiddleWare);
291
220
```
292
221
关于参数含义和` LifecycleMiddleWares ` 可参考:[ agent-reducer] ( https://www.npmjs.com/package/agent-reducer )
293
222
294
- 5 . AgentProvider
223
+ 4 . AgentProvider
295
224
296
225
` use-agent-reducer ` 提供的一个` react ` Context.Provider组件,可为当前范围内所有需要使用已有` agent ` 的子组件提供Context便利。
297
226
@@ -301,11 +230,12 @@ const agent=useAgent(OriginAgent);
301
230
return (
302
231
<AgentProvider value={agent}>
303
232
{children}
304
- </AgentProvider>
233
+ </AgentProvider>
305
234
)
306
235
```
236
+ ` useMiddleActions ` 和对应的模型可以在任何地方直接引用 ( import ),所以就不为其设定provider了。
307
237
308
- 6 . useAgentContext ( >=2.0.0 ) ~~ useParent ( <2.0.0 )~~
238
+ 5 . useAgentContext ( >=2.0.0 ) ~~ useParent ( <2.0.0 )~~
309
239
310
240
配合` AgentProvider ` 使用,直接读取最近一层AgentProvider传入的agent对象。
311
241
0 commit comments