Skip to content

Commit d2ee83c

Browse files
author
wangyi
committed
发布3.1.0
1 parent 4bf7b8b commit d2ee83c

File tree

4 files changed

+176
-18
lines changed

4 files changed

+176
-18
lines changed

README.md

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -183,15 +183,32 @@ OriginAgent : class | new class();
183183
184184
MiddleWare : 见 agent-reducer
185185
186-
env : {strict?:boolean}
186+
env : {strict?:boolean,legacy?:boolean}
187187
188188
const agent = useAgent(OriginAgent, MiddleWare? | env?, env?);
189189
```
190-
`env`参数,我们只开放了strict,如果希望在处理之后,渲染之前立即改变`this.state`可以把它设置为`false`
190+
`env`参数,如果希望在处理之后,渲染之前立即改变`this.state`可以把`env.strict`设置为`false`;
191+
如果希望使用 1.* 版本的`agent-reducer`,可以将`env.legacy`设置为`true`
192+
也可以使用`agent-reducer``globalConfig`进行全局设置。
191193

192194
关于其他参数含义可参考:[agent-reducer](https://www.npmjs.com/package/agent-reducer)
193195

194-
2 . useMiddleActions ( >=2.0.0 3.0.0:接口更改 )
196+
2 . useAgentReducer ( >=3.1.0 )
197+
198+
用来创建一个稳定的agent对象,可用于代替`useState``useReducer`,用法与`useAgent`一样,
199+
但使用的`agent-reducer`版本锁死在 3.* 版本,不受全局环境影响,`env.legacy`对该方法不生效。
200+
201+
```
202+
OriginAgent : class | new class();
203+
204+
MiddleWare : 见 agent-reducer
205+
206+
env : {strict?:boolean}
207+
208+
const agent = useAgentReducer(OriginAgent, MiddleWare? | env?, env?);
209+
```
210+
211+
3 . useMiddleActions ( >=2.0.0 3.0.0:接口更改 )
195212

196213
配合`useAgent`使用,用于管理调用`agent`,用于异步请求后`dispatch`或做其他任何事情。
197214

@@ -208,7 +225,7 @@ const middles = useMiddleActions(Middles,agent?,...MiddleWare|LifecycleMiddleWar
208225
```
209226
关于参数含义可参考:[agent-reducer](https://www.npmjs.com/package/agent-reducer)
210227

211-
3 . useMiddleWare ( >=2.0.0 )
228+
4 . useMiddleWare ( >=2.0.0 ) ~~useBranch ( <2.0.0 )~~
212229

213230
复制`agent`,获得一个拥有可控生命周期的`agent`,有点类似git的分支概念,复制版与原版`agent`的非方法属性完全同步。
214231
可通过附加`MiddleWare``LifecycleMiddleWare`控制复制版`agent`的特性。
@@ -220,7 +237,7 @@ const branch=useMiddleWare(agent, MiddleWare | LifecycleMiddleWare);
220237
```
221238
关于参数含义和`LifecycleMiddleWares`可参考:[agent-reducer](https://www.npmjs.com/package/agent-reducer)
222239

223-
4 . AgentProvider
240+
5 . AgentProvider
224241

225242
`use-agent-reducer`提供的一个`react` Context.Provider组件,可为当前范围内所有需要使用已有`agent`的子组件提供Context便利。
226243

@@ -235,7 +252,7 @@ return (
235252
```
236253
`useMiddleActions`和对应的模型可以在任何地方直接引用 ( import ),所以就不为其设定provider了。
237254

238-
5 . useAgentContext ( >=2.0.0 ) ~~useParent ( <2.0.0 )~~
255+
6 . useAgentContext ( >=2.0.0 ) ~~useParent ( <2.0.0 )~~
239256

240257
配合`AgentProvider`使用,直接读取最近一层AgentProvider传入的agent对象。
241258

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "use-agent-reducer",
3-
"version": "3.0.0",
3+
"version": "3.1.0",
44
"main": "./index.js",
55
"author": "Jimmy.Harding",
66
"description": "the purpose of this project is make useReducer classify",
@@ -31,10 +31,10 @@
3131
"peerDependencies": {
3232
"react": ">=16.8.0",
3333
"react-dom": ">=16.8.0",
34-
"agent-reducer": "^3.0.0"
34+
"agent-reducer": "^3.1.0"
3535
},
3636
"dependencies": {
37-
"agent-reducer": "^3.0.0"
37+
"agent-reducer": "^3.1.1"
3838
},
3939
"devDependencies": {
4040
"@babel/core": "7.2.2",

src/index.ts

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,11 @@ class AgentShipping {
4949
const AgentContext = React.createContext<AgentShipping | null>(null);
5050

5151
export type RunEnv = {
52-
strict?: boolean
52+
strict?: boolean,
53+
legacy?:boolean
5354
};
5455

55-
export function useAgent<T extends OriginAgent<S>,S>(entry: T | { new(): T }, middleWareOrEnv?: MiddleWare | RunEnv, env?: RunEnv): T {
56+
export function useAgentReducer<T extends OriginAgent<S>, S>(entry: T | { new(): T }, middleWareOrEnv?: MiddleWare | RunEnv, env?: Omit<RunEnv,'legacy'>): T {
5657

5758
const runEnv = typeof middleWareOrEnv !== 'function' ? middleWareOrEnv : env;
5859

@@ -61,6 +62,7 @@ export function useAgent<T extends OriginAgent<S>,S>(entry: T | { new(): T }, mi
6162
let {current: reducer} = useRef(createAgentReducer(entry, middleWare, {
6263
...runEnv,
6364
...env,
65+
legacy: false,
6466
expired: false,
6567
updateBy: 'manual'
6668
}));
@@ -78,29 +80,65 @@ export function useAgent<T extends OriginAgent<S>,S>(entry: T | { new(): T }, mi
7880
return reducer.agent;
7981
}
8082

83+
export function useAgent<T extends OriginAgent<S>, S>(entry: T | { new(): T }, middleWareOrEnv?: MiddleWare | RunEnv, env?: RunEnv): T {
84+
85+
const runEnv = typeof middleWareOrEnv !== 'function' ? middleWareOrEnv : env;
86+
87+
const middleWare = typeof middleWareOrEnv === 'function' ? middleWareOrEnv : undefined;
88+
89+
let {current: reducer} = useRef(createAgentReducer(entry, middleWare, {
90+
...runEnv,
91+
...env,
92+
expired: false,
93+
updateBy: 'manual'
94+
}));
95+
96+
const [state, dispatch] = useReducer(reducer, reducer.initialState);
97+
98+
reducer.update(state, dispatch);
99+
100+
useEffect(() => {
101+
return () => {
102+
reducer.env.expired = true;
103+
}
104+
}, []);
105+
106+
return reducer.agent;
107+
108+
}
109+
81110
export function useMiddleActions<T extends OriginAgent<S>, P extends MiddleActions<T, S>, S = any>(
82111
middleActions: { new(agent: T): P },
83112
agent?: T,
84113
...middleWare: (MiddleWare | LifecycleMiddleWare)[]
85114
): P {
86-
const ref= useRef(useAgentMiddleActions(middleActions,agent,...middleWare) as P);
115+
const ref = useRef(useAgentMiddleActions(middleActions, agent, ...middleWare) as P);
87116
return ref.current;
88117
}
89118

90-
export function useMiddleWare<T extends OriginAgent<S>,S>(agent: T, middleWare: MiddleWare | LifecycleMiddleWare) {
91-
const {current} = useRef(useAgentMiddleWare(agent, middleWare));
119+
export function useMiddleWare<T extends OriginAgent<S>, S>(agent: T, ...middleWare: (MiddleWare | LifecycleMiddleWare)[]) {
120+
const {current} = useRef(useAgentMiddleWare(agent, ...middleWare));
92121
return current;
93122
}
94123

95-
export function AgentProvider<T extends OriginAgent<S>,S>({value, children}: { readonly value: T, readonly children?: ReactNodeLike }) {
124+
/**
125+
* @deprecated
126+
* @param agent
127+
* @param middleWare
128+
*/
129+
export function useBranch<T extends OriginAgent<S>, S>(agent: T, middleWare: MiddleWare | LifecycleMiddleWare) {
130+
return useMiddleWare(agent, middleWare);
131+
}
132+
133+
export function AgentProvider<T extends OriginAgent<S>, S>({value, children}: { readonly value: T, readonly children?: ReactNodeLike }) {
96134
let ref = useRef(new AgentShipping(value));
97135
useEffect(() => {
98136
ref.current.update(value);
99137
}, [value.state]);
100138
return React.createElement(AgentContext.Provider, {value: ref.current}, children);
101139
}
102140

103-
export function useAgentContext<T extends OriginAgent>() {
141+
export function useAgentContext<T extends OriginAgent>():T {
104142

105143
const shipping = useContext(AgentContext);
106144

@@ -119,4 +157,11 @@ export function useAgentContext<T extends OriginAgent>() {
119157
}, [shipping]);
120158

121159
return ref.current as T;
160+
}
161+
162+
/**
163+
* @deprecated
164+
*/
165+
export function useParent<T extends OriginAgent>():T {
166+
return useAgentContext<T>();
122167
}

test/spec/basic.spec.tsx

Lines changed: 98 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,24 @@
11
import React, {useEffect} from "react";
22
import {renderHook, act} from "@testing-library/react-hooks";
33
import {render} from "@testing-library/react";
4-
import {AgentProvider, useAgent, useAgentContext, useMiddleActions, useMiddleWare} from "../../src";
5-
import { MiddleActions, middleWare, MiddleWarePresets, OriginAgent} from "agent-reducer";
4+
import {
5+
AgentProvider,
6+
useAgent,
7+
useAgentContext,
8+
useAgentReducer,
9+
useBranch,
10+
useMiddleActions,
11+
useMiddleWare
12+
} from "../../src";
13+
import {
14+
BranchResolvers,
15+
clearGlobalConfig,
16+
globalConfig,
17+
MiddleActions,
18+
middleWare,
19+
MiddleWarePresets,
20+
OriginAgent
21+
} from "agent-reducer";
622
import {ReactNodeLike} from "prop-types";
723

824
describe('使用基本的useAgent', () => {
@@ -192,4 +208,84 @@ describe('使用useMiddleWare复制一个专注一种任务模式的agent', () =
192208
expect(div.innerHTML).toBe('1');
193209
});
194210

211+
});
212+
213+
describe('使用 3.1.0+ 对 1.* 版的兼容功能',()=>{
214+
215+
beforeAll(()=>{
216+
//在顶级将环境设置为 1.* 模式。
217+
globalConfig({env:{legacy:true}});
218+
});
219+
220+
afterAll(()=>{
221+
//注意:正式使用时,不要调用该方法
222+
clearGlobalConfig();
223+
})
224+
225+
class CountAgent implements OriginAgent<number> {
226+
227+
state = 0;
228+
229+
stepUp = (): number => this.state + 1;
230+
231+
stepDown = (): number => this.state - 1;
232+
233+
sum = (...counts: number[]): number => this.state + counts.reduce((r, c): number => r + c, 0);
234+
235+
step = (isUp: boolean) => isUp ? this.stepUp() : this.stepDown();
236+
237+
doubleDispatchStep(isUp: boolean) {
238+
return isUp ? this.stepUp() : this.stepDown();
239+
}
240+
241+
// 在 1.* 中起作用,在 3.1.0+ 中需要使用 MiddleWare 的方法
242+
async callingSum(tms: number) {
243+
await new Promise((r) => setTimeout(r, tms * 100));
244+
return this.sum(tms); // 注意:3.1.0+ 中 this.sum 是个纯粹的方法调用,本身并不会修改 this.state,所以需要 return,否则this.state将变成undefined
245+
}
246+
247+
async callingSumByLegacy(tms: number) {
248+
await new Promise((r) => setTimeout(r, tms * 100));
249+
this.sum(tms); // 注意:1.* 中因为 this 的层层代理作用,加上 middle-action 作用, this.sum 会修改 this.state,所以不需要 return
250+
}
251+
252+
}
253+
254+
test('1.* 用法',async ()=>{
255+
// useAgent 会收到全局 env.legacy 影响,变成 1.* 支持版本
256+
const {result: ar} = renderHook(() => useAgent(CountAgent));
257+
const {result: mr} = renderHook(() => useBranch(ar.current, BranchResolvers.takeLatest()));
258+
await act(async () => {
259+
const first = mr.current.callingSumByLegacy(5);
260+
const second = mr.current.callingSumByLegacy(2);
261+
await Promise.all([first, second]);
262+
});
263+
expect(ar.current.state).toBe(2);
264+
});
265+
266+
test('3.* 用法',async ()=>{
267+
// useAgentReducer 只支持 3.0.0 以上写法,并忽略全局 env.legacy 设置
268+
const {result: ar} = renderHook(() => useAgentReducer(CountAgent));
269+
const {result: mr} = renderHook(() => useMiddleWare(ar.current, MiddleWarePresets.takeLatest()));
270+
await act(async () => {
271+
const first = mr.current.callingSum(5);
272+
const second = mr.current.callingSum(2);
273+
await Promise.all([first, second]);
274+
});
275+
expect(ar.current.state).toBe(2);
276+
});
277+
278+
test('3.* 使用 1.* 的写法',async ()=>{
279+
// useAgentReducer 只支持 3.0.0 以上写法,并忽略全局 env.legacy 设置
280+
const {result: ar} = renderHook(() => useAgentReducer(CountAgent));
281+
const {result: mr} = renderHook(() => useMiddleWare(ar.current, MiddleWarePresets.takeLatest()));
282+
await act(async () => {
283+
const first = mr.current.callingSumByLegacy(5);
284+
// 注意:3.1.0+ 中 this.sum 是个纯粹的方法调用,本身并不会修改 this.state,所以需要 return,否则this.state将变成undefined
285+
const second = mr.current.callingSumByLegacy(2);
286+
await Promise.all([first, second]);
287+
});
288+
expect(ar.current.state).toBe(undefined);
289+
});
290+
195291
});

0 commit comments

Comments
 (0)