@webkrafters/react-observable-context 4.1.7 → 4.1.9
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 +68 -26
- package/dist/main/hooks/use-store/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -86,6 +86,48 @@ A context bearing an observable consumer [store](#store). State changes within t
|
|
|
86
86
|
|
|
87
87
|
<h1 id="getting-started">Getting Started</h1>
|
|
88
88
|
|
|
89
|
+
<i><b><u>index.js</u></b></i>
|
|
90
|
+
|
|
91
|
+
```jsx
|
|
92
|
+
import React from 'react';
|
|
93
|
+
import ReactDOM from 'react-dom';
|
|
94
|
+
import App from './app';
|
|
95
|
+
|
|
96
|
+
ReactDOM.render( <App />, document.getElementById( 'root' ) );
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
<i><b><u>app.js</u></b></i>
|
|
100
|
+
|
|
101
|
+
```jsx
|
|
102
|
+
import React, { useEffect, useState } from 'react';
|
|
103
|
+
import ProviderDeno from './provider-demo';
|
|
104
|
+
|
|
105
|
+
const MILLIS_PER_MINUTE = 6e4;
|
|
106
|
+
|
|
107
|
+
let numCreated = 0;
|
|
108
|
+
|
|
109
|
+
const App = () => {
|
|
110
|
+
const [ age, updateAge ] = useState( 0 );
|
|
111
|
+
const [ testNumber ] = useState( () => ++numCreated );
|
|
112
|
+
|
|
113
|
+
useEffect(() => {
|
|
114
|
+
const t = setTimeout(
|
|
115
|
+
() => updateAge( age => age + 1 ),
|
|
116
|
+
MILLIS_PER_MINUTE
|
|
117
|
+
);
|
|
118
|
+
return () => clearTimeout( t );
|
|
119
|
+
}, [ age ]);
|
|
120
|
+
|
|
121
|
+
return (
|
|
122
|
+
<div>
|
|
123
|
+
<h2>App instance #: { testNumber }</H2>
|
|
124
|
+
<ProviderDeno ageInMinutes={ age } />
|
|
125
|
+
</div>
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
export default App;
|
|
129
|
+
```
|
|
130
|
+
|
|
89
131
|
<i id="create-context-usage"><u><b>context.js</b></u></i>
|
|
90
132
|
|
|
91
133
|
```jsx
|
|
@@ -93,23 +135,27 @@ import { createContext } from '@webkrafters/react-observable-context';
|
|
|
93
135
|
export default createContext();
|
|
94
136
|
```
|
|
95
137
|
|
|
96
|
-
<i id="provider-usage"><b><u>provider.js</u></b></i>
|
|
138
|
+
<i id="provider-usage"><b><u>provider-demo.js</u></b></i>
|
|
97
139
|
|
|
98
140
|
```jsx
|
|
99
141
|
import React, { useEffect, useState } from 'react';
|
|
100
142
|
import ObservableContext from './context';
|
|
101
143
|
import Ui from './ui';
|
|
102
144
|
|
|
103
|
-
const
|
|
145
|
+
const createInitialState = c = ({
|
|
146
|
+
a: { b: { c, x: { y: { z: [ 2022 ] } } } }
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
const ProviderDemo = ({ ageInMinutes: c = 0 }) => {
|
|
104
150
|
|
|
105
|
-
const [ state, setState ] = useState(() => (
|
|
106
|
-
a: { b: { c, x: { y: { z: [ 2022 ] } } } }
|
|
107
|
-
}));
|
|
151
|
+
const [ state, setState ] = useState(() => createInitialState( c ));
|
|
108
152
|
|
|
109
153
|
useEffect(() => {
|
|
110
154
|
// similar to `store.setState`, use the following to update
|
|
111
155
|
// only the changed slice of the context internal state.
|
|
112
|
-
|
|
156
|
+
// Please see `Set State` section
|
|
157
|
+
setState({ a: { b: { c } } }); // OR
|
|
158
|
+
// setState({ a: { b: { c: { '@@REPLACE': c } } } });
|
|
113
159
|
// Do not do the following: it will override the context internal state.
|
|
114
160
|
// setState({ ...state, a: { ...state.a, b: { ...state.a.b, c } } });
|
|
115
161
|
}, [ c ]);
|
|
@@ -120,9 +166,9 @@ const Provider = ({ c = 36 }) => {
|
|
|
120
166
|
</ObservableContext.Provider>
|
|
121
167
|
);
|
|
122
168
|
};
|
|
123
|
-
|
|
169
|
+
ProviderDemo.displayName = 'ProviderDemo';
|
|
124
170
|
|
|
125
|
-
export default
|
|
171
|
+
export default ProviderDemo;
|
|
126
172
|
```
|
|
127
173
|
|
|
128
174
|
<i id="connect-usage"><u><b>ui.js</b></u> (connect method)</i>
|
|
@@ -133,13 +179,16 @@ import { connect } from '@webkrafters/react-observable-context';
|
|
|
133
179
|
import ObservableContext from './context';
|
|
134
180
|
|
|
135
181
|
export const YearText = ({ data }) => ( <div>Year: { data.year }</div> );
|
|
136
|
-
|
|
182
|
+
|
|
183
|
+
export const YearInput = ({ data, resetState, setState }) => {
|
|
137
184
|
const onChange = useCallback( e => setState({
|
|
138
185
|
a: { b: { x: { y: { z: { 0: e.target.value } } } } }
|
|
139
186
|
}), [ setState ]);
|
|
187
|
+
|
|
140
188
|
useEffect(() => {
|
|
141
189
|
data.year > 2049 && resetState([ 'a.b.c' ]);
|
|
142
190
|
}, [ data.year ]);
|
|
191
|
+
|
|
143
192
|
return ( <div>Year: <input type="number" onChange={ onChange } /> );
|
|
144
193
|
};
|
|
145
194
|
|
|
@@ -173,12 +222,15 @@ const Client1 = memo(() => { // memoize to prevent 'no-change' renders from the
|
|
|
173
222
|
|
|
174
223
|
const Client2 = memo(() => { // memoize to prevent 'no-change' renders from the parent.
|
|
175
224
|
const { data, setState, resetState } = useContext( ObservableContext, selectorMap );
|
|
225
|
+
|
|
176
226
|
const onChange = useCallback( e => setState({
|
|
177
227
|
a: { b: { x: { y: { z: { 0: e.target.value } } } } }
|
|
178
228
|
}), [ setState ]);
|
|
229
|
+
|
|
179
230
|
useEffect(() => {
|
|
180
231
|
data.year > 2049 && resetState([ 'a.b.c' ]);
|
|
181
232
|
}, [ data.year ]);
|
|
233
|
+
|
|
182
234
|
return ( <div>Year: <input type="number" onChange={ onChange } /> );
|
|
183
235
|
});
|
|
184
236
|
|
|
@@ -192,16 +244,6 @@ const Ui = () => (
|
|
|
192
244
|
export default Ui;
|
|
193
245
|
```
|
|
194
246
|
|
|
195
|
-
<i><b><u>index.js</u></b></i>
|
|
196
|
-
|
|
197
|
-
```jsx
|
|
198
|
-
import React from 'react';
|
|
199
|
-
import ReactDOM from 'react-dom';
|
|
200
|
-
import Provider from './provider';
|
|
201
|
-
|
|
202
|
-
ReactDOM.render( <Provider />, document.getElementById( 'root' ) );
|
|
203
|
-
```
|
|
204
|
-
|
|
205
247
|
# API
|
|
206
248
|
|
|
207
249
|
The React-Observable-Context module exports named constants and the following **4** main entities namely:
|
|
@@ -514,7 +556,7 @@ const state = {
|
|
|
514
556
|
|
|
515
557
|
store.setState({ '@@REPLACE': { a: 'Demo', j: 17 } }) // rewrites state to { a: 'Demo', j: 17 };
|
|
516
558
|
|
|
517
|
-
store.setState({ a: { '@@REPLACE': { message: 'Testing...' } } }) // rewrites state.a
|
|
559
|
+
store.setState({ a: { '@@REPLACE': { message: 'Testing...' } } }) // rewrites state.a to { message: 'Testing...' }
|
|
518
560
|
|
|
519
561
|
/* rewrites state.a.b[1] to { x: 97, y: 98, z: 99 }; leaving state.a.b = [{ x: 7, y: 8, z: 9 }, { x: 97, y: 98, z: 99 }] */
|
|
520
562
|
store.setState({ a: { b: [ state.a.b[ 0 ], { '@@REPLACE': { x: 97, y: 98, z: 99 } } ] } })
|
|
@@ -527,11 +569,11 @@ store.setState({ a: { b: { 1: { '@@REPLACE': { x: 97, y: 98, z: 99 } } } } })
|
|
|
527
569
|
|
|
528
570
|
```jsx
|
|
529
571
|
/*
|
|
530
|
-
This tag is for handling edge cases only. Please use sparingly. In most cases, store.setState with or without any of the other tags is sufficient and most efficient.
|
|
531
|
-
|
|
532
|
-
This and the '@@REPLACE' tags are functionally equivalent when used with a replacement value argument.
|
|
533
|
-
|
|
534
|
-
Be aware that the compute function argument may be `undefined` for properties which do not yet exist in the state.
|
|
572
|
+
This tag is for handling edge cases only. Please use sparingly. In most cases, store.setState with or without any of the other tags is sufficient and most efficient.
|
|
573
|
+
|
|
574
|
+
This and the '@@REPLACE' tags are functionally equivalent when used with a replacement value argument.
|
|
575
|
+
|
|
576
|
+
Be aware that the compute function argument may be `undefined` for properties which do not yet exist in the state.
|
|
535
577
|
*/
|
|
536
578
|
|
|
537
579
|
const state = {
|
|
@@ -541,7 +583,7 @@ const state = {
|
|
|
541
583
|
|
|
542
584
|
store.setState({ '@@SET': currentValue => ({ ...currentValue, a: 'Demo', j: 17 }) }) // rewrites state to { ...state, a: 'Demo', j: 17 };
|
|
543
585
|
|
|
544
|
-
store.setState({ a: { '@@SET': currentValue => ({ ...currentValue, message: 'Testing...' }) } }) // rewrites state.a
|
|
586
|
+
store.setState({ a: { '@@SET': currentValue => ({ ...currentValue, message: 'Testing...' }) } }) // rewrites state.a to { ...state, message: 'Testing...' }
|
|
545
587
|
|
|
546
588
|
/* rewrites state.a.b[1] to { x: 97, y: 98, z: 99 }; leaving state.a.b = [{ x: 7, y: 8, z: 9 }, { x: 97, y: 98, z: 99 }] */
|
|
547
589
|
store.setState({ a: { b: [ state.a.b[ 0 ], { '@@SET': currentValue => ({ ...currentValue, x: 97, y: 98, z: 99 }) } ] } })
|
|
@@ -100,7 +100,7 @@ var useStore = function useStore(prehooks, value, storage) {
|
|
|
100
100
|
mounted.current = true;
|
|
101
101
|
return;
|
|
102
102
|
}
|
|
103
|
-
setState(
|
|
103
|
+
setState(value);
|
|
104
104
|
}, [value]);
|
|
105
105
|
(0, _react.useEffect)(function () {
|
|
106
106
|
if (!listeners.size) {
|
package/package.json
CHANGED