react-native-onyx 2.0.126 → 2.0.128
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 +4 -21
- package/dist/Onyx.js +1 -1
- package/dist/types.d.ts +0 -2
- package/dist/useOnyx.d.ts +3 -13
- package/dist/useOnyx.js +1 -7
- package/dist/withOnyx/index.js +4 -14
- package/dist/withOnyx/types.d.ts +2 -14
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -61,30 +61,23 @@ The data will then be cached and stored via [`AsyncStorage`](https://github.com/
|
|
|
61
61
|
|
|
62
62
|
### Performance Options for Large Objects
|
|
63
63
|
|
|
64
|
-
For performance-critical scenarios with large objects, `Onyx.set()` accepts optional
|
|
64
|
+
For performance-critical scenarios with large objects, `Onyx.set()` accepts optional flag to skip expensive operations:
|
|
65
65
|
|
|
66
66
|
```javascript
|
|
67
67
|
Onyx.set(ONYXKEYS.LARGE_DATA, computedValue, {
|
|
68
68
|
skipCacheCheck: true, // Skip deep equality check
|
|
69
|
-
skipNullRemoval: true, // Skip null value pruning
|
|
70
69
|
});
|
|
71
70
|
```
|
|
72
71
|
|
|
73
72
|
**Options:**
|
|
74
73
|
- `skipCacheCheck`: Skips the deep equality comparison with the cached value. By default, Onyx compares new values against cached ones to avoid unnecessary updates. For large objects, this comparison can be expensive.
|
|
75
|
-
- `skipNullRemoval`: Skips the removal of `null` values from nested objects. By default, Onyx removes `null` values before storage. Use this when `null` values are meaningful in your data structure.
|
|
76
74
|
|
|
77
75
|
#### When to Use SetOptions
|
|
78
76
|
- **Use `skipCacheCheck: true`** for:
|
|
79
77
|
- Large objects where deep equality checking is expensive
|
|
80
78
|
- Values that you know have changed
|
|
81
79
|
|
|
82
|
-
|
|
83
|
-
- Computed values where `null` represents a legitimate result
|
|
84
|
-
- Data structures where `null` has semantic meaning
|
|
85
|
-
- Values that should preserve their exact structure
|
|
86
|
-
|
|
87
|
-
**Note**: These options are recommended only for large objects where performance is critical. Most use cases should use the standard `Onyx.set(key, value)` syntax.
|
|
80
|
+
**Note**: These option is recommended only for large objects where performance is critical. Most use cases should use the standard `Onyx.set(key, value)` syntax.
|
|
88
81
|
|
|
89
82
|
## Merging data
|
|
90
83
|
|
|
@@ -196,16 +189,7 @@ export default withOnyx({
|
|
|
196
189
|
})(App);
|
|
197
190
|
```
|
|
198
191
|
|
|
199
|
-
Differently from `useOnyx()`, `withOnyx()` will delay the rendering of the wrapped component until all keys/entities have been fetched and passed to the component, this can be convenient for simple cases. This however, can really delay your application if many entities are connected to the same component
|
|
200
|
-
|
|
201
|
-
```javascript
|
|
202
|
-
export default withOnyx({
|
|
203
|
-
session: {
|
|
204
|
-
key: ONYXKEYS.SESSION,
|
|
205
|
-
initialValue: {}
|
|
206
|
-
},
|
|
207
|
-
})(App);
|
|
208
|
-
```
|
|
192
|
+
Differently from `useOnyx()`, `withOnyx()` will delay the rendering of the wrapped component until all keys/entities have been fetched and passed to the component, this can be convenient for simple cases. This however, can really delay your application if many entities are connected to the same component.
|
|
209
193
|
|
|
210
194
|
Additionally, if your component has many keys/entities when your component will mount but will receive many updates as data is fetched from DB and passed down to it, as every key that gets fetched will trigger a `setState` on the `withOnyx` HOC. This might cause re-renders on the initial mounting, preventing the component from mounting/rendering in reasonable time, making your app feel slow and even delaying animations.
|
|
211
195
|
|
|
@@ -221,8 +205,7 @@ const App = ({session, markReadyForHydration}) => (
|
|
|
221
205
|
// Second argument to funciton is `shouldDelayUpdates`
|
|
222
206
|
export default withOnyx({
|
|
223
207
|
session: {
|
|
224
|
-
key: ONYXKEYS.SESSION
|
|
225
|
-
initialValue: {}
|
|
208
|
+
key: ONYXKEYS.SESSION
|
|
226
209
|
},
|
|
227
210
|
}, true)(App);
|
|
228
211
|
```
|
package/dist/Onyx.js
CHANGED
|
@@ -186,7 +186,7 @@ function set(key, value, options) {
|
|
|
186
186
|
OnyxUtils_1.default.logKeyRemoved(OnyxUtils_1.default.METHOD.SET, key);
|
|
187
187
|
return Promise.resolve();
|
|
188
188
|
}
|
|
189
|
-
const valueWithoutNestedNullValues =
|
|
189
|
+
const valueWithoutNestedNullValues = utils_1.default.removeNestedNullValues(value);
|
|
190
190
|
const hasChanged = (options === null || options === void 0 ? void 0 : options.skipCacheCheck) ? true : OnyxCache_1.default.hasValueChanged(key, valueWithoutNestedNullValues);
|
|
191
191
|
OnyxUtils_1.default.logKeyChanged(OnyxUtils_1.default.METHOD.SET, key, value, hasChanged);
|
|
192
192
|
// This approach prioritizes fast UI changes without waiting for data to be stored in device storage.
|
package/dist/types.d.ts
CHANGED
|
@@ -374,8 +374,6 @@ type OnyxUpdate = {
|
|
|
374
374
|
type SetOptions = {
|
|
375
375
|
/** Skip the deep equality check against the cached value. Improves performance for large objects. */
|
|
376
376
|
skipCacheCheck?: boolean;
|
|
377
|
-
/** Skip pruning null values from the object. Improves performance for large objects. */
|
|
378
|
-
skipNullRemoval?: boolean;
|
|
379
377
|
};
|
|
380
378
|
/**
|
|
381
379
|
* Represents the options used in `Onyx.init()` method.
|
package/dist/useOnyx.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { DependencyList } from 'react';
|
|
2
2
|
import type { OnyxKey, OnyxValue } from './types';
|
|
3
|
-
type
|
|
3
|
+
type UseOnyxSelector<TKey extends OnyxKey, TReturnValue = OnyxValue<TKey>> = (data: OnyxValue<TKey> | undefined) => TReturnValue;
|
|
4
|
+
type UseOnyxOptions<TKey extends OnyxKey, TReturnValue> = {
|
|
4
5
|
/**
|
|
5
6
|
* Determines if this key in this subscription is safe to be evicted.
|
|
6
7
|
*/
|
|
@@ -29,15 +30,6 @@ type BaseUseOnyxOptions = {
|
|
|
29
30
|
* is not there, it will log an alert, as it means we are using data that no one loaded and that's most probably a bug.
|
|
30
31
|
*/
|
|
31
32
|
canBeMissing?: boolean;
|
|
32
|
-
};
|
|
33
|
-
type UseOnyxInitialValueOption<TInitialValue> = {
|
|
34
|
-
/**
|
|
35
|
-
* This value will be returned by the hook on the first render while the data is being read from Onyx.
|
|
36
|
-
*/
|
|
37
|
-
initialValue?: TInitialValue;
|
|
38
|
-
};
|
|
39
|
-
type UseOnyxSelector<TKey extends OnyxKey, TReturnValue = OnyxValue<TKey>> = (data: OnyxValue<TKey> | undefined) => TReturnValue;
|
|
40
|
-
type UseOnyxSelectorOption<TKey extends OnyxKey, TReturnValue> = {
|
|
41
33
|
/**
|
|
42
34
|
* This will be used to subscribe to a subset of an Onyx key's data.
|
|
43
35
|
* Using this setting on `useOnyx` can have very positive performance benefits because the component will only re-render
|
|
@@ -47,14 +39,12 @@ type UseOnyxSelectorOption<TKey extends OnyxKey, TReturnValue> = {
|
|
|
47
39
|
*/
|
|
48
40
|
selector?: UseOnyxSelector<TKey, TReturnValue>;
|
|
49
41
|
};
|
|
50
|
-
type UseOnyxOptions<TKey extends OnyxKey, TReturnValue> = BaseUseOnyxOptions & UseOnyxInitialValueOption<TReturnValue> & UseOnyxSelectorOption<TKey, TReturnValue>;
|
|
51
42
|
type FetchStatus = 'loading' | 'loaded';
|
|
52
43
|
type ResultMetadata<TValue> = {
|
|
53
44
|
status: FetchStatus;
|
|
54
45
|
sourceValue?: NonNullable<TValue> | undefined;
|
|
55
46
|
};
|
|
56
47
|
type UseOnyxResult<TValue> = [NonNullable<TValue> | undefined, ResultMetadata<TValue>];
|
|
57
|
-
declare function useOnyx<TKey extends OnyxKey, TReturnValue = OnyxValue<TKey>>(key: TKey, options?:
|
|
58
|
-
declare function useOnyx<TKey extends OnyxKey, TReturnValue = OnyxValue<TKey>>(key: TKey, options?: BaseUseOnyxOptions & UseOnyxInitialValueOption<NoInfer<TReturnValue>>, dependencies?: DependencyList): UseOnyxResult<TReturnValue>;
|
|
48
|
+
declare function useOnyx<TKey extends OnyxKey, TReturnValue = OnyxValue<TKey>>(key: TKey, options?: UseOnyxOptions<TKey, TReturnValue>, dependencies?: DependencyList): UseOnyxResult<TReturnValue>;
|
|
59
49
|
export default useOnyx;
|
|
60
50
|
export type { FetchStatus, ResultMetadata, UseOnyxResult, UseOnyxOptions };
|
package/dist/useOnyx.js
CHANGED
|
@@ -141,12 +141,6 @@ function useOnyx(key, options, dependencies = []) {
|
|
|
141
141
|
newValueRef.current = undefined;
|
|
142
142
|
newFetchStatus = 'loading';
|
|
143
143
|
}
|
|
144
|
-
// If data is not present in cache and `initialValue` is set during the first connection,
|
|
145
|
-
// we set the new value to `initialValue` and fetch status to `loaded` since we already have some data to return to the consumer.
|
|
146
|
-
if (isFirstConnectionRef.current && !hasCacheForKey && (options === null || options === void 0 ? void 0 : options.initialValue) !== undefined) {
|
|
147
|
-
newValueRef.current = options.initialValue;
|
|
148
|
-
newFetchStatus = 'loaded';
|
|
149
|
-
}
|
|
150
144
|
// We do a deep equality check if `selector` is defined, since each `tryGetCachedValue()` call will
|
|
151
145
|
// generate a plain new primitive/object/array that was created using the `selector` function.
|
|
152
146
|
// For the other cases we will only deal with object reference checks, so just a shallow equality check is enough.
|
|
@@ -183,7 +177,7 @@ function useOnyx(key, options, dependencies = []) {
|
|
|
183
177
|
}
|
|
184
178
|
}
|
|
185
179
|
return resultRef.current;
|
|
186
|
-
}, [options === null || options === void 0 ? void 0 : options.initWithStoredValues, options === null || options === void 0 ? void 0 : options.allowStaleData, options === null || options === void 0 ? void 0 : options.
|
|
180
|
+
}, [options === null || options === void 0 ? void 0 : options.initWithStoredValues, options === null || options === void 0 ? void 0 : options.allowStaleData, options === null || options === void 0 ? void 0 : options.canBeMissing, key, selectorRef]);
|
|
187
181
|
const subscribe = (0, react_1.useCallback)((onStoreChange) => {
|
|
188
182
|
isConnectingRef.current = true;
|
|
189
183
|
onStoreChangeFnRef.current = onStoreChange;
|
package/dist/withOnyx/index.js
CHANGED
|
@@ -39,7 +39,7 @@ const OnyxCache_1 = __importDefault(require("../OnyxCache"));
|
|
|
39
39
|
const OnyxConnectionManager_1 = __importDefault(require("../OnyxConnectionManager"));
|
|
40
40
|
// This is a list of keys that can exist on a `mapping`, but are not directly related to loading data from Onyx. When the keys of a mapping are looped over to check
|
|
41
41
|
// if a key has changed, it's a good idea to skip looking at these properties since they would have unexpected results.
|
|
42
|
-
const mappingPropertiesToIgnoreChangesTo = ['
|
|
42
|
+
const mappingPropertiesToIgnoreChangesTo = ['allowStaleData'];
|
|
43
43
|
/**
|
|
44
44
|
* Returns the display name of a component
|
|
45
45
|
*/
|
|
@@ -85,11 +85,8 @@ function default_1(mapOnyxToState, shouldDelayUpdates = false) {
|
|
|
85
85
|
this.activeConnections = {};
|
|
86
86
|
const cachedState = mapOnyxToStateEntries(mapOnyxToState).reduce((resultObj, [propName, mapping]) => {
|
|
87
87
|
const key = Str.result(mapping.key, props);
|
|
88
|
-
|
|
88
|
+
const value = OnyxUtils_1.default.tryGetCachedValue(key, mapping);
|
|
89
89
|
const hasCacheForKey = OnyxCache_1.default.hasCacheForKey(key);
|
|
90
|
-
if (!hasCacheForKey && !value && mapping.initialValue) {
|
|
91
|
-
value = mapping.initialValue;
|
|
92
|
-
}
|
|
93
90
|
/**
|
|
94
91
|
* If we have a pending merge for a key it could mean that data is being set via Onyx.merge() and someone expects a component to have this data immediately.
|
|
95
92
|
*
|
|
@@ -220,15 +217,8 @@ function default_1(mapOnyxToState, shouldDelayUpdates = false) {
|
|
|
220
217
|
if (key === 'loading') {
|
|
221
218
|
return result;
|
|
222
219
|
}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
// an update has already been received and we can discard the value we are trying to hydrate
|
|
226
|
-
if (initialValue !== undefined && prevState[key] !== undefined && prevState[key] !== initialValue && prevState[key] !== null) {
|
|
227
|
-
// eslint-disable-next-line no-param-reassign
|
|
228
|
-
result[key] = prevState[key];
|
|
229
|
-
}
|
|
230
|
-
else if (prevState[key] !== undefined && prevState[key] !== null) {
|
|
231
|
-
// if value is already there (without initial value) then we can discard the value we are trying to hydrate
|
|
220
|
+
// if value is already there then we can discard the value we are trying to hydrate
|
|
221
|
+
if (prevState[key] !== undefined && prevState[key] !== null) {
|
|
232
222
|
// eslint-disable-next-line no-param-reassign
|
|
233
223
|
result[key] = prevState[key];
|
|
234
224
|
}
|
package/dist/withOnyx/types.d.ts
CHANGED
|
@@ -9,18 +9,6 @@ type BaseMapping<TComponentProps, TOnyxProps> = {
|
|
|
9
9
|
initWithStoredValues?: boolean;
|
|
10
10
|
allowStaleData?: boolean;
|
|
11
11
|
};
|
|
12
|
-
/**
|
|
13
|
-
* Represents the base mapping options when an Onyx collection key is supplied.
|
|
14
|
-
*/
|
|
15
|
-
type CollectionBaseMapping<TOnyxKey extends CollectionKeyBase> = {
|
|
16
|
-
initialValue?: OnyxCollection<KeyValueMapping[TOnyxKey]>;
|
|
17
|
-
};
|
|
18
|
-
/**
|
|
19
|
-
* Represents the base mapping options when an Onyx non-collection key is supplied.
|
|
20
|
-
*/
|
|
21
|
-
type EntryBaseMapping<TOnyxKey extends OnyxKey> = {
|
|
22
|
-
initialValue?: OnyxEntry<KeyValueMapping[TOnyxKey]>;
|
|
23
|
-
};
|
|
24
12
|
/**
|
|
25
13
|
* Represents the string / function `key` mapping option between an Onyx key and the component's prop.
|
|
26
14
|
*
|
|
@@ -87,7 +75,7 @@ type BaseMappingFunctionKeyAndSelector<TComponentProps, TOnyxProps, TReturnType,
|
|
|
87
75
|
/**
|
|
88
76
|
* Represents the mapping options between an Onyx key and the component's prop with all its possibilities.
|
|
89
77
|
*/
|
|
90
|
-
type Mapping<TComponentProps, TOnyxProps, TOnyxProp extends keyof TOnyxProps, TOnyxKey extends OnyxKey> = BaseMapping<TComponentProps, TOnyxProps> &
|
|
78
|
+
type Mapping<TComponentProps, TOnyxProps, TOnyxProp extends keyof TOnyxProps, TOnyxKey extends OnyxKey> = BaseMapping<TComponentProps, TOnyxProps> & (BaseMappingKey<TComponentProps, TOnyxProps, TOnyxProp, TOnyxKey, OnyxEntry<KeyValueMapping[TOnyxKey]>> | BaseMappingStringKeyAndSelector<TComponentProps, TOnyxProps, TOnyxProps[TOnyxProp], TOnyxKey> | BaseMappingFunctionKeyAndSelector<TComponentProps, TOnyxProps, TOnyxProps[TOnyxProp], TOnyxKey>);
|
|
91
79
|
/**
|
|
92
80
|
* Represents a superset of `Mapping` type with internal properties included.
|
|
93
81
|
*/
|
|
@@ -98,7 +86,7 @@ type WithOnyxMapping<TComponentProps, TOnyxProps> = Mapping<TComponentProps, TOn
|
|
|
98
86
|
/**
|
|
99
87
|
* Represents the mapping options between an Onyx collection key without suffix and the component's prop with all its possibilities.
|
|
100
88
|
*/
|
|
101
|
-
type CollectionMapping<TComponentProps, TOnyxProps, TOnyxProp extends keyof TOnyxProps, TOnyxKey extends CollectionKeyBase> = BaseMapping<TComponentProps, TOnyxProps> &
|
|
89
|
+
type CollectionMapping<TComponentProps, TOnyxProps, TOnyxProp extends keyof TOnyxProps, TOnyxKey extends CollectionKeyBase> = BaseMapping<TComponentProps, TOnyxProps> & (BaseMappingKey<TComponentProps, TOnyxProps, TOnyxProp, TOnyxKey, OnyxCollection<KeyValueMapping[TOnyxKey]>> | BaseMappingStringKeyAndSelector<TComponentProps, TOnyxProps, ExtractOnyxCollectionValue<TOnyxProps[TOnyxProp]>, TOnyxKey> | BaseMappingFunctionKeyAndSelector<TComponentProps, TOnyxProps, ExtractOnyxCollectionValue<TOnyxProps[TOnyxProp]>, TOnyxKey>);
|
|
102
90
|
/**
|
|
103
91
|
* Represents an union type of all the possible Onyx key mappings.
|
|
104
92
|
* Each `OnyxPropMapping` will be associated with its respective Onyx key, ensuring different type-safety for each object.
|