Skip to content

Commit 6adac54

Browse files
authored
Merge pull request #7 from filefoxper/3.2.5
add API useAgentSelector and useAgentMethods
2 parents 0afa823 + 4b2c732 commit 6adac54

File tree

14 files changed

+538
-190
lines changed

14 files changed

+538
-190
lines changed

.eslintignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.eslintrc.js
2+
test/
3+
jest.config.js
4+
babel.config.js
5+
index.js
6+
webpack.config.js

.eslintrc.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
module.exports = {
2+
env: {
3+
"browser": true,
4+
"es6": true
5+
},
6+
extends: [
7+
'airbnb',
8+
'plugin:@typescript-eslint/recommended',
9+
// 'plugin:@typescript-eslint/recommended-requiring-type-checking'
10+
],
11+
globals: {
12+
"Atomics": "readonly",
13+
"SharedArrayBuffer": "readonly",
14+
"self": "readonly"
15+
},
16+
parserOptions: {
17+
"ecmaVersion": 2021,
18+
"sourceType": 'module',
19+
tsconfigRootDir: '.',
20+
project: ['./tsconfig.json'],
21+
},
22+
plugins: ['@typescript-eslint'],
23+
settings: {
24+
'import/resolver': {
25+
'typescript': {},
26+
27+
}
28+
},
29+
rules: {
30+
"import/extensions": "off",
31+
"no-param-reassign": "off",
32+
"@typescript-eslint/no-explicit-any":"off",
33+
"@typescript-eslint/no-unused-vars": ["off"],
34+
'react/jsx-filename-extension': ["off", { 'extensions': ['.js', '.jsx', '.ts', '.tsx'] }],
35+
'react/jsx-props-no-spreading':'off',
36+
'import/prefer-default-export':'off',
37+
'max-classes-per-file':'off',
38+
'no-plusplus':["error",{allowForLoopAfterthoughts:true}],
39+
'react/require-default-props':'off',
40+
'camelcase':'off',
41+
"no-use-before-define": "off",
42+
"@typescript-eslint/no-use-before-define": ["error", { "functions": false, "classes": true }],
43+
'react/no-did-update-set-state':'warn',
44+
"no-shadow":["warn"],
45+
'class-methods-use-this':'off',
46+
'jsx-a11y/no-static-element-interactions':'off',
47+
'jsx-a11y/click-events-have-key-events':'off',
48+
'@typescript-eslint/no-empty-function':'off'
49+
}
50+
};

CHANGE_LOG.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,8 @@
66
这时`useAgent`只支持`agent-reducer@1.*`特性,
77
`useAgentReducer`方法因不受全局影响,依然只支持`agent-reducer@3.*`
88

9-
[update] 重新增加被去除的`use-agent-reducer@1.*`方法:useBranch,useParent作为废弃方法。
9+
[update] 重新增加被去除的`use-agent-reducer@1.*`方法:useBranch,useParent作为废弃方法。
10+
11+
## v3.2.5 2021-04-10
12+
13+
[new] add API `useAgentSelector` and `useAgentMethods`

docs/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88

99
# use-agent-reducer
1010

11-
This is a powerful `react hook` library for managing component state changes. It is designed for replacing reducer tools in `react hook` ecosystem. You can manage the major component state change logistic with it by a class or object model pattern.
11+
This is a powerful `react hook` library for managing state changes. It is designed for replacing reducer tools in `react hook` ecosystem. You can design a state change logistic by setting a model with class or object pattern.
1212

13-
The core dependency of this library is [agent-reducer](https://www.npmjs.com/package/agent-reducer), you can read its [document](https://github.com/filefoxper/agent-reducer/blob/master/documents/en/index.md) for a preview about what `use-agent-reducer` can do. But, we suggest you follow our [document](/introduction) and learn how to use it first.
13+
The core dependency of this library is [agent-reducer](https://github.com/filefoxper/agent-reducer/blob/master/documents/en/index.md), you can read its document for a preview about what `use-agent-reducer` can do. But, we suggest you follow our [document](/introduction) and learn how to use it first.
1414

1515
* [Introduction](introduction.md)
1616
* [Tutorial](/tutorial.md)

docs/_sidebar.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
* [Introduction](introduction.md)
33
* [Tutorial](/tutorial.md)
44
* [Guides](/guides.md)
5-
* [API Reference](/api.md)
5+
* [API Reference](/api.md)
6+
* [Change Logs](/changes.md)

docs/api.md

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ function useAgentReducer<T extends OriginAgent<S>, S>(
1212
): T
1313
```
1414

15-
* originAgent - the model class or object.
15+
* entry - the model class or object.
1616
* middleWareOrEnv - it is an optional param, if you want to use `MiddleWare`, it can be a `MiddleWare`, if you want to set running env without `MiddleWare`, it can be an env config.
1717
* env - if you want to set both `MiddleWare` and running env, you can set an env config here.
1818

@@ -41,19 +41,53 @@ function useMiddleWare<T extends OriginAgent<S>, S>(
4141

4242
You can see how to use it [here](/tutorial?id=use-middleware).
4343

44-
## useAgent
44+
## useAgentSelector
45+
46+
This api function is a react hook, it can be used to extract data from a sharing model state. And only the extracted data change can cause its consumer (react component) rerender.
47+
48+
```typescript
49+
export function useAgentSelector<T extends OriginAgent<S>, S, R>(
50+
entry: T,
51+
mapStateCallback: (state: T['state']) => R,
52+
): R
53+
```
54+
55+
* entry - the model instance object.
56+
* mapStateCallback - a callback function for extracting data from model state.
57+
58+
This function returns data extracted from a model state directly.
59+
60+
## useAgentMethods
61+
62+
This api function is a react hook for calling a model methods. It never causes its consumer (react component) rerendering.
63+
64+
```typescript
65+
export function useAgentMethods<T extends OriginAgent<S>, S>(
66+
entry: T,
67+
middleWareOrEnv?: MiddleWare | RunEnv,
68+
env?: Omit<RunEnv, 'legacy'>,
69+
): Omit<T, 'state'>
70+
```
71+
72+
* entry - the model instance object.
73+
* middleWareOrEnv - it is an optional param, if you want to use `MiddleWare`, it can be a `MiddleWare`, if you want to set running env without `MiddleWare`, it can be an env config.
74+
* env - if you want to set both `MiddleWare` and running env, you can set an env config here.
75+
76+
This function returns a model like instance which has an empty state property. It only provides model methods.
77+
78+
## ~~useAgent~~
4579

4680
(not recommend)
4781

4882
This api function is an old version abount [useAgentReducer](/api?id=useagentreducer), it is kept for supporting the old features of [agent-reducer](https://www.npmjs.com/package/agent-reducer). And we do not recommend to use it.
4983

50-
## useBranch
84+
## ~~useBranch~~
5185

5286
(not recommend)
5387

5488
This api function is an old version abount [useMiddleWare](/api?id=usemiddleware). And we do not recommend to use it.
5589

56-
## useMiddleActions
90+
## ~~useMiddleActions~~
5791

5892
(not recommend)
5993

@@ -71,7 +105,7 @@ function useMiddleActions<T extends OriginAgent<S>, P extends MiddleActions<T, S
71105
* middleActions - a instance of class extends MiddleActions
72106
* otherParams - start an `Agent` object, and rest with MiddleWares
73107

74-
## AgentProvider
108+
## ~~AgentProvider~~
75109

76110
(not recommend)
77111

@@ -88,7 +122,7 @@ interface Props{
88122
* value - the `Agent` object for sharing in `AgentProvider` children.
89123
* children - react nodes
90124

91-
## useAgentContext
125+
## ~~useAgentContext~~
92126

93127
(not recommend)
94128

@@ -100,7 +134,7 @@ This is a react hook function, it picks `Agent` from a nearest [AgentProvider](/
100134
function useAgentContext<T extends OriginAgent>(): T
101135
```
102136

103-
## useParent
137+
## ~~useParent~~
104138

105139
(not recommend)
106140

docs/guides.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,3 +207,42 @@ describe("set run env",()=>{
207207

208208
Be careful in `env.strict`, you'd better not set it to be `false`. For it will make the state difference between `Agent` and your reducer tool.
209209

210+
## model sharing optimization
211+
212+
By using `model sharing`, we can share state updating between different components. But this feature brings problem too, that causes model sharing consumers( react components ) always render together, no matter if the state change is necessary for urrent consumer. From `use-agent-reducer@3.2.5`, we provide some new API functions for resolving this problem. You can use API function `useAgentSelector` to extract data from a model state which is truly used in component. And also, you can extract methods from a sharing model by using another API `useAgentMethods`.
213+
214+
API `useAgentSelector` extracts data from a state, and only the extracted data change can cause its consumer (react component) rerender.
215+
216+
```typescript
217+
import {weakSharing} from 'agent-reducer';
218+
import {useAgentSelector} from 'use-agent-reducer';
219+
220+
// model sharing reference
221+
const sharingRef = weakSharing(()=> Model);
222+
223+
......
224+
225+
// use a sharing model,
226+
// and extract data from state by a state mapping function.
227+
// Only the extracted data change can cause its consumer rerender.
228+
const renderNeeds = useAgentSelector(sharingRef.current, (state)=> state.renderNeeds);
229+
```
230+
231+
API `useAgentMethods` only provides methods from a model like instance, it never causes a rerender.
232+
233+
```typescript
234+
import {weakSharing, MiddleWarePresets} from 'agent-reducer';
235+
import {useAgentMethods} from 'use-agent-reducer';
236+
237+
// model sharing reference
238+
const sharingRef = weakSharing(()=> Model);
239+
240+
......
241+
242+
// use a sharing model,
243+
// get a model like instance, which omits the state property.
244+
// It is used for providing methods from sharing model,
245+
// and it never causes a rerender.
246+
const {fetchState} = useAgentMethods(sharingRef.current, MiddleWarePresets.takePromiseResolve());
247+
```
248+

docs/introduction.md

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
# Introduction
22

3-
The primary work of this tool is using a `state producible model` to generate a `state changeable agent`. The agent changes state according to what the model produces out. So, [Model](/introduction?id=model) and [Agent](/introduction?id=agent) are very important in this document.
3+
The primary work of this tool is generating a `state changeable agent` from its `state producible model`. An agent changes state according to what its model produces out. So, [Model](/introduction?id=model) and [Agent](/introduction?id=agent) are very important concepts in this document.
44

5-
## motivation
5+
## Motivation
66

7-
The core library [agent-reducer](https://www.npmjs.com/package/agent-reducer) is a powerful independent tool for managing state changes. But it can not work in `react` directly, so we designed this library to connect `agent-reducer` with `react hooks`.
7+
The core library [agent-reducer](https://www.npmjs.com/package/agent-reducer) is a powerful independent tool for managing state changes. But it can not work in `react` system directly, so we designed this library to connect `agent-reducer` with `react hooks`.
88

99
## Concept
1010

11-
There are two concepts we have mentioned above, `Model` and `Agent`. And we will explain the details about these concepts in this section.
11+
There are two concepts we have mentioned above, `Model` and `Agent`. They will be explained in this section.
1212

1313
#### Model
1414

15-
`Model` is a class or an object which describes what kind of data you want to maintian and how to produce new one. We can describe the maintainable data with a property name `state`, and prepare some state producing methods in `Model`. In `agent-reducer`, concept `Model` has another name `OriginAgent`, but here, we call it `Model`.
15+
`Model` is a class or an object which describes what kind of data you want to maintian and how to produce a new one. You can describe a maintainable data with property name `state` in `Model`, and prepare some state producible methods beside. In `agent-reducer`, concept `Model` has another name `OriginAgent`, but here, we call it `Model`.
1616

17-
1. Property `state` stores the data you want to maintian, it can be any type. Do not modify `state` manual, it is very important.
17+
1. Property `state` stores the data you want to maintian, it can be any type. Do not modify `state` manually, this may causes some problems.
1818
2. `method` is a function for producing a new `state`. You can consider what returns from a `method` as a new state.
1919

2020
This is a `Model` example:
@@ -24,7 +24,7 @@ import {OriginAgent} from 'agent-reducer';
2424

2525
// model
2626
class CountAgent implements OriginAgent<number> {
27-
// with a initial state
27+
// set a initial state
2828
state = 0;
2929

3030
// use arrow function to produce a new state
@@ -51,9 +51,9 @@ class CountAgent implements OriginAgent<number> {
5151

5252
#### Agent
5353

54-
`Agent` is a Proxy object, it provides a latest state and methods for changing state. You can create an `Agent` object by using api useAgentReducer. A class model is always transformed into a instance object first by this api, then to be proxied as an `Agent` object.
54+
`Agent` is a Proxy object, it provides a newest state and some methods base on the same name methods in its `Model` for changing state. You can create an `Agent` object by using api useAgentReducer with a `Model`.
5555

56-
The state of `Agent` object always keeps equal with its model state.
56+
The state of `Agent` object always keeps equal with its `Model` state.
5757

5858
```typescript
5959
import {OriginAgent} from 'agent-reducer';
@@ -90,11 +90,11 @@ The `use-agent-reducer` package lives in [npm](https://www.npmjs.com/get-npm). T
9090
```
9191
npm i use-agent-reducer
9292
```
93-
You'd better add `agent-reducer` into your package.json dependencies too. When you are installing package `use-agent-reducer`, a `agent-reducer` package is always brought into your dependencies, but this can not resolve the problem: when you are developing with `use-agent-reducer`, you can not find `agent-reducer` helper easily.
93+
You'd better add `agent-reducer` into your package.json dependencies too. When you are installing package `use-agent-reducer`, a `agent-reducer` package is always brought into your `node_modules` directory, but this is not helpful for using `agent-reducer` API.
9494

9595
## Getting started
9696

97-
This section describes how to create a model, and how to call `agent-reducer` for help. After reading this section, you can master the basic usage of `use-agent-reducer`.
97+
This section describes how to create a model, and how to call `agent-reducer` API for help. After reading this section, you can master the basic usage of `use-agent-reducer`.
9898

9999
#### create model
100100

docs/zh/_sidebar.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
* [介绍](/zh/introduction.md)
33
* [教程](/zh/tutorial.md)
44
* [引导](/zh/guides.md)
5-
* [API 文档](/zh/api.md)
5+
* [API 文档](/zh/api.md)
6+
* [更新日志](/zh/changes.md)

docs/zh/api.md

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ function useAgentReducer<T extends OriginAgent<S>, S>(
1212
): T
1313
```
1414

15-
* originAgent - 模型,可以是 class 也可以是 object
15+
* entry - 模型,可以是 class 也可以是 object
1616
* middleWareOrEnv - 可选参数,如果想要设置 MiddleWare ,就传入 MiddleWare ,如果不想使用 MiddleWare ,想要配置运行环境参数,则传入环境配置。
1717
* env - 可选参数,如果想同时使用 MiddleWare 和 环境配置,请通过该参数传入环境配置。
1818

@@ -41,19 +41,53 @@ function useMiddleWare<T extends OriginAgent<S>, S>(
4141

4242
[使用案例](/zh/tutorial?id=use-middleware).
4343

44-
## useAgent
44+
## useAgentSelector
45+
46+
这是一个 react hook 方法,可用于提取被共享模型 state 中的部分数据,若被提取数据保持不变,则不会触发组件渲染。
47+
48+
```typescript
49+
export function useAgentSelector<T extends OriginAgent<S>, S, R>(
50+
entry: T,
51+
mapStateCallback: (state: T['state']) => R,
52+
): R
53+
```
54+
55+
* entry - 模型实例 object
56+
* mapStateCallback - state 提取方法,用于提取当前模型实例 state 的部分数据,如果被提取数据保持不变则不会触发组件渲染。
57+
58+
该方法返回值即为被提取数据。
59+
60+
## useAgentMethods
61+
62+
这是一个 react hook 方法,可用于提取被共享模型中的方法,该 hook 本身不会触发当前使用组件渲染。
63+
64+
```typescript
65+
export function useAgentMethods<T extends OriginAgent<S>, S>(
66+
entry: T,
67+
middleWareOrEnv?: MiddleWare | RunEnv,
68+
env?: Omit<RunEnv, 'legacy'>,
69+
): Omit<T, 'state'>
70+
```
71+
72+
* entry - 模型实例 object
73+
* middleWareOrEnv - 可选参数,如果想要设置 MiddleWare ,就传入 MiddleWare ,如果不想使用 MiddleWare ,想要配置运行环境参数,则传入环境配置。
74+
* env - 可选参数,如果想同时使用 MiddleWare 和 环境配置,请通过该参数传入环境配置。
75+
76+
该方法返回值为忽略了 state 数据的模型实例。
77+
78+
## ~~useAgent~~
4579

4680
(不推荐)
4781

4882
当前 API 接口为老版本的 [useAgentReducer](/zh/api?id=useagentreducer)。
4983

50-
## useBranch
84+
## ~~useBranch~~
5185

5286
(不推荐)
5387

5488
当前 API 接口为老版本的 [useMiddleWare](/zh/api?id=usemiddleware)。
5589

56-
## useMiddleActions
90+
## ~~useMiddleActions~~
5791

5892
(不推荐)
5993

@@ -69,7 +103,7 @@ function useMiddleActions<T extends OriginAgent<S>, P extends MiddleActions<T, S
69103
* middleActions - 继承 MiddleActions 的 class
70104
* middleWare - MiddleWares
71105

72-
## AgentProvider
106+
## ~~AgentProvider~~
73107

74108
(不推荐)
75109

@@ -86,7 +120,7 @@ interface Props{
86120
* value - `Agent` 代理对象,用于 children 共享。
87121
* children - react 组件
88122

89-
## useAgentContext
123+
## ~~useAgentContext~~
90124

91125
(不推荐)
92126

@@ -98,7 +132,7 @@ interface Props{
98132
function useAgentContext<T extends OriginAgent>(): T
99133
```
100134

101-
## useParent
135+
## ~~useParent~~
102136

103137
(不推荐)
104138

0 commit comments

Comments
 (0)