react-chain-of-responsibility 0.3.0-main.cf60397 → 0.3.0-main.e6dfb8e
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/README.md +36 -37
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -14,13 +14,13 @@ Click here for [our live demo](https://compulim.github.io/react-chain-of-respons
|
|
|
14
14
|
|
|
15
15
|
## How to use?
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
3 steps to adopt the chain of responsibility pattern.
|
|
18
18
|
|
|
19
19
|
1. [Create a chain](#create-a-chain)
|
|
20
20
|
1. [Register handlers in the chain](#register-handlers-in-the-chain)
|
|
21
21
|
1. [Make a render request](#make-a-render-request)
|
|
22
22
|
|
|
23
|
-
In this sample, we will use chain of responsibility pattern to create a file preview UI
|
|
23
|
+
In this sample, we will use chain of responsibility pattern to create a file preview UI which can handle various file types.
|
|
24
24
|
|
|
25
25
|
### Create a chain
|
|
26
26
|
|
|
@@ -77,19 +77,19 @@ const Binary = ({ url }) => <a href={url}>{url}</a>;
|
|
|
77
77
|
const middleware = [asMiddleware(Image), asMiddleware(Video), asMiddleware(Binary)];
|
|
78
78
|
```
|
|
79
79
|
|
|
80
|
-
In this sample, 3 middleware
|
|
80
|
+
In this sample, 3 middleware are registered:
|
|
81
81
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
82
|
+
- `<Image>` will render `<img>` if content type is `'image/*'`, otherwise, will pass to next middleware (`<Video>`)
|
|
83
|
+
- `<Video>` will render `<video>` if content type is `'video/*'`, otherwise, will pass to next middleware (`<Binary>`)
|
|
84
|
+
- `<Binary>` is a catch-all and will render as a link
|
|
85
85
|
|
|
86
|
-
Notes:
|
|
86
|
+
Notes: props passed to `<Next>` will override original props, however, `request` cannot be overridden.
|
|
87
87
|
|
|
88
88
|
### Make a render request
|
|
89
89
|
|
|
90
|
-
Before calling any components or hooks, the `<Provider>` component must be
|
|
90
|
+
Before calling any components or hooks, the `<Provider>` component must be set up with the chain.
|
|
91
91
|
|
|
92
|
-
When `<Proxy>` is being rendered, it will pass the `request` to the chain. The component returned from the chain will be rendered with `...props`. If no component is returned, it will
|
|
92
|
+
When `<Proxy>` is being rendered, it will pass the `request` to the chain. The component returned from the chain will be rendered with `...props`. If no component is returned, it will be rendered as `undefined`.
|
|
93
93
|
|
|
94
94
|
```tsx
|
|
95
95
|
render(
|
|
@@ -115,7 +115,7 @@ For advanced scenario with precise rendering control, use the `useBuildComponent
|
|
|
115
115
|
|
|
116
116
|
## How should I use?
|
|
117
117
|
|
|
118
|
-
Here are some recipes leveraging the chain of responsibility pattern for UI composition
|
|
118
|
+
Here are some recipes on leveraging the chain of responsibility pattern for UI composition.
|
|
119
119
|
|
|
120
120
|
### Bring your own component
|
|
121
121
|
|
|
@@ -180,12 +180,11 @@ For example, in a date picker UI, using the chain of responsibility pattern enab
|
|
|
180
180
|
The "which component to render" decision in the middleware enables 4 key customization techniques:
|
|
181
181
|
|
|
182
182
|
- Add a new component
|
|
183
|
-
- Register a new `<Audio>` middleware component to handle content type of
|
|
183
|
+
- Register a new `<Audio>` middleware component to handle content type of "audio/\*"
|
|
184
184
|
- Replace an existing component
|
|
185
|
-
- Register a new `<
|
|
186
|
-
- The original `<Image>` will be replaced through starvation
|
|
185
|
+
- Register a new `<Image2>` middleware component to handle content type of "image/\*"
|
|
187
186
|
- Remove an existing component
|
|
188
|
-
- Return `undefined` when handling content type of
|
|
187
|
+
- Return `undefined` when handling content type of "video/\*"
|
|
189
188
|
- Decorate an existing component
|
|
190
189
|
- Return a component which render `<div class="my-border"><Next /></div>`
|
|
191
190
|
|
|
@@ -195,15 +194,15 @@ After a bundle is lazy-loaded, register the component in the middleware.
|
|
|
195
194
|
|
|
196
195
|
When the chain of the `<Provider>` is updated, the lazy-loaded component will be rendered immediately.
|
|
197
196
|
|
|
198
|
-
This recipe can also
|
|
197
|
+
This recipe can also used to build multiple flavors of bundle and allow bundle to be composited to suit the apps need.
|
|
199
198
|
|
|
200
199
|
## Advanced usage
|
|
201
200
|
|
|
202
|
-
### Registering component
|
|
201
|
+
### Registering component using functional pattern
|
|
203
202
|
|
|
204
|
-
The `asMiddleware()` is a helper function to turn a React component into a middleware for simpler registration. As it operates in render-time, there are disadvantages. For example, a VDOM node is always required.
|
|
203
|
+
The `asMiddleware()` is a helper function to turn a React component into a component middleware for simpler registration. As it operates in render-time, there are disadvantages. For example, a VDOM node is always required.
|
|
205
204
|
|
|
206
|
-
If precise rendering control is
|
|
205
|
+
If precise rendering control is a requirement, consider registering the component natively using functional programming.
|
|
207
206
|
|
|
208
207
|
The following code snippet shows the conversion from the `<Image>` middleware component in our previous sample, into a component registered via functional programming.
|
|
209
208
|
|
|
@@ -346,13 +345,13 @@ function createChainOfResponsibility<Request = undefined, Props = { children?: n
|
|
|
346
345
|
|
|
347
346
|
### Return value
|
|
348
347
|
|
|
349
|
-
| Name | Description
|
|
350
|
-
| --------------------------- |
|
|
351
|
-
| `asMiddleware` | A helper function to convert a React component into a middleware.
|
|
352
|
-
| `Provider` | Entrypoint component, must wraps all usage of customizations
|
|
353
|
-
| `Proxy` | Proxy component, process the `request` from props and morph into the result component
|
|
354
|
-
| `types` | TypeScript: shorthand types, all objects are `undefined` intentionally
|
|
355
|
-
| `useBuildComponentCallback` | Callback hook which return a function to build the component for rendering the
|
|
348
|
+
| Name | Description |
|
|
349
|
+
| --------------------------- | ------------------------------------------------------------------------------------- |
|
|
350
|
+
| `asMiddleware` | A helper function to convert a React component into a middleware. |
|
|
351
|
+
| `Provider` | Entrypoint component, must wraps all usage of customizations |
|
|
352
|
+
| `Proxy` | Proxy component, process the `request` from props and morph into the result component |
|
|
353
|
+
| `types` | TypeScript: shorthand types, all objects are `undefined` intentionally |
|
|
354
|
+
| `useBuildComponentCallback` | Callback hook which return a function to build the component for rendering the result |
|
|
356
355
|
|
|
357
356
|
### Options
|
|
358
357
|
|
|
@@ -367,26 +366,26 @@ type Options = {
|
|
|
367
366
|
|
|
368
367
|
If `passModifiedRequest` is default or `false`, middleware will not be allowed to pass another reference of `request` object to their `next()` middleware. Instead, the `request` object passed to `next()` will be ignored and the next middleware always receive the original `request` object. This behavior is similar to [Express](https://expressjs.com/) middleware.
|
|
369
368
|
|
|
370
|
-
Setting to `true` will enable advanced scenarios and allow
|
|
369
|
+
Setting to `true` will enable advanced scenarios and allow a middleware to influence their downstreamers.
|
|
371
370
|
|
|
372
|
-
When the option is default or `false
|
|
371
|
+
When the option is default or `false`, middleware could still modify the `request` object and influence their downstreamers. It is recommended to follow immutable pattern when handling the `request` object, or use deep [`Object.freeze()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze) to guarantee immutability.
|
|
373
372
|
|
|
374
373
|
### API of `asMiddleware`
|
|
375
374
|
|
|
376
|
-
`asMiddleware` wraps a React component into a middleware. Build will be done through additional `middleware` prop.
|
|
377
|
-
|
|
378
375
|
```ts
|
|
379
376
|
function asMiddleware(
|
|
380
377
|
middlewareComponent: ComponentType<MiddlewareComponentProps<Request, Props, Init>>
|
|
381
378
|
): ComponentMiddleware<Request, Props, Init>;
|
|
382
379
|
|
|
380
|
+
type MiddlewareProps<Request, Props, Init> = Readonly<{
|
|
381
|
+
init: Init;
|
|
382
|
+
Next: ComponentType<Partial<Props>>;
|
|
383
|
+
request: Request;
|
|
384
|
+
}>;
|
|
385
|
+
|
|
383
386
|
type MiddlewareComponentProps<Request, Props, Init> = Props &
|
|
384
387
|
Readonly<{
|
|
385
|
-
middleware:
|
|
386
|
-
init: Init;
|
|
387
|
-
Next: ComponentType<Partial<Props>>;
|
|
388
|
-
request: Request;
|
|
389
|
-
}>
|
|
388
|
+
middleware: MiddlewareProps<Request, Props, Init>
|
|
390
389
|
}>;
|
|
391
390
|
```
|
|
392
391
|
|
|
@@ -401,9 +400,9 @@ type UseBuildComponentCallback<Request, Props> = (
|
|
|
401
400
|
) => ComponentType<Props> | undefined;
|
|
402
401
|
```
|
|
403
402
|
|
|
404
|
-
For simplicity, instead of returning a
|
|
403
|
+
For simplicity, instead of returning a component or `false`/`null`/`undefined`, the `useBuildComponentCallback` will only return a component or `undefined`.
|
|
405
404
|
|
|
406
|
-
The `fallbackComponent` is a component which all unhandled requests will sink into, including calls
|
|
405
|
+
The `fallbackComponent` is a component which all unhandled requests will sink into, including calls without ancestral `<Provider>`.
|
|
407
406
|
|
|
408
407
|
### API for Fluent UI
|
|
409
408
|
|
|
@@ -433,7 +432,7 @@ When rendering the element, `getKey` is called to compute the `key` attribute. T
|
|
|
433
432
|
|
|
434
433
|
## Designs
|
|
435
434
|
|
|
436
|
-
###
|
|
435
|
+
### What is the difference between request, and props?
|
|
437
436
|
|
|
438
437
|
- Request is for *appearance*, while props is for *content*
|
|
439
438
|
- Request is for *deciding which component to render*, while props is for *what to render*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-chain-of-responsibility",
|
|
3
|
-
"version": "0.3.0-main.
|
|
3
|
+
"version": "0.3.0-main.e6dfb8e",
|
|
4
4
|
"description": "Using chain of responsibility design pattern for compositing and customizing React component.",
|
|
5
5
|
"files": [
|
|
6
6
|
"./dist/"
|
|
@@ -131,6 +131,6 @@
|
|
|
131
131
|
"react": ">=16.8.0"
|
|
132
132
|
},
|
|
133
133
|
"dependencies": {
|
|
134
|
-
"react-chain-of-responsibility": "^0.3.0-main.
|
|
134
|
+
"react-chain-of-responsibility": "^0.3.0-main.e6dfb8e"
|
|
135
135
|
}
|
|
136
136
|
}
|