From b6c6db314cd35e3cbf4d8ea94245f7995e5885bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Henriques?= Date: Thu, 9 May 2024 13:16:55 +0100 Subject: [PATCH 01/11] Only use deepEqual on useOnyx if key is a collection one and selector is defined --- lib/useOnyx.ts | 15 +++++++++++---- tests/unit/useOnyxTest.ts | 2 +- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/lib/useOnyx.ts b/lib/useOnyx.ts index aa51af64..305c8297 100644 --- a/lib/useOnyx.ts +++ b/lib/useOnyx.ts @@ -1,11 +1,11 @@ -import {deepEqual} from 'fast-equals'; +import {deepEqual, shallowEqual} from 'fast-equals'; import {useCallback, useEffect, useRef, useSyncExternalStore} from 'react'; import type {IsEqual} from 'type-fest'; +import Onyx from './Onyx'; import OnyxUtils from './OnyxUtils'; import type {CollectionKeyBase, KeyValueMapping, NonNull, OnyxCollection, OnyxEntry, OnyxKey, Selector} from './types'; import useLiveRef from './useLiveRef'; import usePrevious from './usePrevious'; -import Onyx from './Onyx'; /** * Represents a Onyx value that can be either a single entry or a collection of entries, depending on the `TKey` provided. @@ -154,9 +154,16 @@ function useOnyx>(key: T newFetchStatus = 'loaded'; } + let areValuesEqual = false; + if (OnyxUtils.isCollectionKey(key) && selectorRef.current) { + areValuesEqual = deepEqual(cachedValueRef.current, newValue); + } else { + areValuesEqual = shallowEqual(cachedValueRef.current, newValue); + } + // If the previously cached value is different from the new value, we update both cached value // and the result to be returned by the hook. - if (!deepEqual(cachedValueRef.current, newValue)) { + if (!areValuesEqual) { cachedValueRef.current = newValue; // If the new value is `null` we default it to `undefined` to ensure the consumer get a consistent result from the hook. @@ -216,4 +223,4 @@ function useOnyx>(key: T export default useOnyx; -export type {UseOnyxResult, ResultMetadata, FetchStatus}; +export type {FetchStatus, ResultMetadata, UseOnyxResult}; diff --git a/tests/unit/useOnyxTest.ts b/tests/unit/useOnyxTest.ts index 04160c51..44eee7a0 100644 --- a/tests/unit/useOnyxTest.ts +++ b/tests/unit/useOnyxTest.ts @@ -206,7 +206,7 @@ describe('useOnyx', () => { const {result} = renderHook(() => useOnyx(ONYXKEYS.COLLECTION.TEST_KEY, { // @ts-expect-error bypass - selector: (entry: OnyxEntry<{id: string; name: string}>) => entry?.id, + selector: (entry: OnyxEntry<{id: string; name: string}>) => ({id: entry?.id}), }), ); From 387d37d7da571e441af65228fce9b1a4549f62b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Henriques?= Date: Thu, 9 May 2024 13:19:02 +0100 Subject: [PATCH 02/11] First try to improve getSnapshot performance --- lib/useOnyx.ts | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/lib/useOnyx.ts b/lib/useOnyx.ts index 305c8297..0b08a1a2 100644 --- a/lib/useOnyx.ts +++ b/lib/useOnyx.ts @@ -3,7 +3,7 @@ import {useCallback, useEffect, useRef, useSyncExternalStore} from 'react'; import type {IsEqual} from 'type-fest'; import Onyx from './Onyx'; import OnyxUtils from './OnyxUtils'; -import type {CollectionKeyBase, KeyValueMapping, NonNull, OnyxCollection, OnyxEntry, OnyxKey, Selector} from './types'; +import type {CollectionKeyBase, KeyValueMapping, NonNull, NonUndefined, OnyxCollection, OnyxEntry, OnyxKey, OnyxValue, Selector} from './types'; import useLiveRef from './useLiveRef'; import usePrevious from './usePrevious'; @@ -90,6 +90,8 @@ function useOnyx>(key: T // We initialize it to `undefined` to simulate that we don't have any value from cache yet. const cachedValueRef = useRef | undefined>(undefined); + const newValueRef = useRef | undefined>(undefined); + // Stores the previously result returned by the hook, containing the data from cache and the fetch status. // We initialize it to `undefined` and `loading` fetch status to simulate the initial result when the hook is loading from the cache. // However, if `initWithStoredValues` is `true` we set the fetch status to `loaded` since we want to signal that data is ready. @@ -134,7 +136,11 @@ function useOnyx>(key: T // If `newValue` is `null` or any other value if means that the cache does have a value for that key. // This difference between `undefined` and other values is crucial and it's used to address the following // conditions and use cases. - let newValue = getCachedValue(key, selectorRef.current); + + // let newValue = getCachedValue(key, selectorRef.current); + if (isFirstConnectionRef.current) { + newValueRef.current = getCachedValue(key, selectorRef.current); + } // Since the fetch status can be different given the use cases below, we define the variable right away. let newFetchStatus: FetchStatus | undefined; @@ -143,28 +149,28 @@ function useOnyx>(key: T // and fetch status to `loading` to simulate that it is still being loaded until we have the most updated data. // If `allowStaleData` is `true` this logic will be ignored and cached value will be used, even if it's stale data. if (isFirstConnectionRef.current && OnyxUtils.hasPendingMergeForKey(key) && !options?.allowStaleData) { - newValue = undefined; + newValueRef.current = undefined; newFetchStatus = 'loading'; } // If data is not present in cache (if it's `undefined`) and `initialValue` is set during the first connection, // we set the new value to `initialValue` and fetch status to `loaded` since we already have some data to return to the consumer. - if (isFirstConnectionRef.current && newValue === undefined && options?.initialValue !== undefined) { - newValue = options?.initialValue as CachedValue; + if (isFirstConnectionRef.current && newValueRef.current === undefined && options?.initialValue !== undefined) { + newValueRef.current = options?.initialValue as CachedValue; newFetchStatus = 'loaded'; } let areValuesEqual = false; if (OnyxUtils.isCollectionKey(key) && selectorRef.current) { - areValuesEqual = deepEqual(cachedValueRef.current, newValue); + areValuesEqual = deepEqual(cachedValueRef.current, newValueRef.current); } else { - areValuesEqual = shallowEqual(cachedValueRef.current, newValue); + areValuesEqual = shallowEqual(cachedValueRef.current, newValueRef.current); } // If the previously cached value is different from the new value, we update both cached value // and the result to be returned by the hook. if (!areValuesEqual) { - cachedValueRef.current = newValue; + cachedValueRef.current = newValueRef.current; // If the new value is `null` we default it to `undefined` to ensure the consumer get a consistent result from the hook. resultRef.current = [(cachedValueRef.current ?? undefined) as CachedValue, {status: newFetchStatus ?? 'loaded'}]; @@ -177,10 +183,17 @@ function useOnyx>(key: T (onStoreChange: () => void) => { connectionIDRef.current = Onyx.connect({ key, - callback: () => { + selector: selectorRef.current, + callback: (value: NonUndefined>) => { // We don't need to update the Onyx cache again here, when `callback` is called the cache is already // expected to be updated, so we just signal that the store changed and `getSnapshot()` can be called again. + + // Should we use removeNestedNullValues()? (it's used on withOnyx) + // const newValue = utils.removeNestedNullValues(value); + const newValue = value; + isFirstConnectionRef.current = false; + newValueRef.current = newValue as CachedValue; onStoreChange(); }, initWithStoredValues: options?.initWithStoredValues, @@ -196,7 +209,7 @@ function useOnyx>(key: T isFirstConnectionRef.current = false; }; }, - [key, options?.initWithStoredValues], + [key, selectorRef, options?.initWithStoredValues], ); // Mimics withOnyx's checkEvictableKeys() behavior. From 364328a0d350831f9dc94f82c5621630666f80a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Henriques?= Date: Fri, 10 May 2024 22:40:59 +0100 Subject: [PATCH 03/11] Fix getSnapshot() improvement --- lib/useOnyx.ts | 33 ++++++++++++++++----------------- tests/unit/useOnyxTest.ts | 22 +++++++++++++++++++++- 2 files changed, 37 insertions(+), 18 deletions(-) diff --git a/lib/useOnyx.ts b/lib/useOnyx.ts index 0b08a1a2..28cb31b7 100644 --- a/lib/useOnyx.ts +++ b/lib/useOnyx.ts @@ -3,7 +3,7 @@ import {useCallback, useEffect, useRef, useSyncExternalStore} from 'react'; import type {IsEqual} from 'type-fest'; import Onyx from './Onyx'; import OnyxUtils from './OnyxUtils'; -import type {CollectionKeyBase, KeyValueMapping, NonNull, NonUndefined, OnyxCollection, OnyxEntry, OnyxKey, OnyxValue, Selector} from './types'; +import type {CollectionKeyBase, KeyValueMapping, NonNull, OnyxCollection, OnyxEntry, OnyxKey, Selector} from './types'; import useLiveRef from './useLiveRef'; import usePrevious from './usePrevious'; @@ -131,14 +131,14 @@ function useOnyx>(key: T }, [previousKey, key]); const getSnapshot = useCallback(() => { - // We get the value from the cache, supplying a selector too in case it's defined. - // If `newValue` is `undefined` it means that the cache doesn't have a value for that key yet. - // If `newValue` is `null` or any other value if means that the cache does have a value for that key. - // This difference between `undefined` and other values is crucial and it's used to address the following - // conditions and use cases. - - // let newValue = getCachedValue(key, selectorRef.current); + // We get the value from cache while the first connection to Onyx is being made, + // so we can return any cached value right away. After the connection is made, we only + // update `newValueRef` when `Onyx.connect()` callback is fired. if (isFirstConnectionRef.current) { + // If `newValueRef.current` is `undefined` it means that the cache doesn't have a value for that key yet. + // If `newValueRef.current` is `null` or any other value if means that the cache does have a value for that key. + // This difference between `undefined` and other values is crucial and it's used to address the following + // conditions and use cases. newValueRef.current = getCachedValue(key, selectorRef.current); } @@ -160,6 +160,10 @@ function useOnyx>(key: T newFetchStatus = 'loaded'; } + // We do a deep equality check if we are subscribed to a collection key and `selector` is defined, + // since each `OnyxUtils.tryGetCachedValue()` call will generate a plain new collection object with new records as well, + // all of them created using the `selector` function. + // For the other cases we will only deal with object reference checks, so just a shallow equality check is enough. let areValuesEqual = false; if (OnyxUtils.isCollectionKey(key) && selectorRef.current) { areValuesEqual = deepEqual(cachedValueRef.current, newValueRef.current); @@ -183,17 +187,12 @@ function useOnyx>(key: T (onStoreChange: () => void) => { connectionIDRef.current = Onyx.connect({ key, - selector: selectorRef.current, - callback: (value: NonUndefined>) => { + callback: () => { // We don't need to update the Onyx cache again here, when `callback` is called the cache is already - // expected to be updated, so we just signal that the store changed and `getSnapshot()` can be called again. - - // Should we use removeNestedNullValues()? (it's used on withOnyx) - // const newValue = utils.removeNestedNullValues(value); - const newValue = value; - + // expected to be updated, so we just get the new value from cache and signal that the store changed, + // making `getSnapshot()` be called again. isFirstConnectionRef.current = false; - newValueRef.current = newValue as CachedValue; + newValueRef.current = getCachedValue(key, selectorRef.current); onStoreChange(); }, initWithStoredValues: options?.initWithStoredValues, diff --git a/tests/unit/useOnyxTest.ts b/tests/unit/useOnyxTest.ts index 44eee7a0..a44ce7c6 100644 --- a/tests/unit/useOnyxTest.ts +++ b/tests/unit/useOnyxTest.ts @@ -195,7 +195,27 @@ describe('useOnyx', () => { expect(result.current[1].status).toEqual('loaded'); }); - it('should not change selected data if a property outside the selector was changed', async () => { + it('should not change selected data if a property outside tha data was changed', async () => { + Onyx.set(ONYXKEYS.TEST_KEY, {id: 'test_id', name: 'test_name'}); + + const {result} = renderHook(() => + useOnyx(ONYXKEYS.TEST_KEY, { + // @ts-expect-error bypass + selector: (entry: OnyxEntry<{id: string; name: string}>) => ({id: entry?.id}), + }), + ); + + await act(async () => waitForPromisesToResolve()); + + const oldResult = result.current; + + await act(async () => Onyx.merge(ONYXKEYS.TEST_KEY, {name: 'test_name_changed'})); + + // must be the same reference + expect(oldResult).toBe(result.current); + }); + + it('should not change selected collection data if a property outside that data was changed', async () => { // @ts-expect-error bypass Onyx.mergeCollection(ONYXKEYS.COLLECTION.TEST_KEY, { [`${ONYXKEYS.COLLECTION.TEST_KEY}entry1`]: {id: 'entry1_id', name: 'entry1_name'}, From d8cf45ecf8dcb1e49cbf82b4e9c7dcf597c47ac2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Henriques?= Date: Wed, 15 May 2024 13:56:11 +0100 Subject: [PATCH 04/11] Optimize getSnapshot() and improve comments --- lib/useOnyx.ts | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/lib/useOnyx.ts b/lib/useOnyx.ts index 28cb31b7..6ca50347 100644 --- a/lib/useOnyx.ts +++ b/lib/useOnyx.ts @@ -106,6 +106,9 @@ function useOnyx>(key: T // in `getSnapshot()` to be satisfied several times. const isFirstConnectionRef = useRef(true); + // Indicates if we should get the newest cached value from Onyx during `getSnapshot()` execution. + const shouldGetCachedValue = useRef(true); + useEffect(() => { // These conditions will ensure we can only handle dynamic collection member keys from the same collection. if (previousKey === key) { @@ -134,12 +137,16 @@ function useOnyx>(key: T // We get the value from cache while the first connection to Onyx is being made, // so we can return any cached value right away. After the connection is made, we only // update `newValueRef` when `Onyx.connect()` callback is fired. - if (isFirstConnectionRef.current) { + if (isFirstConnectionRef.current || shouldGetCachedValue.current) { // If `newValueRef.current` is `undefined` it means that the cache doesn't have a value for that key yet. // If `newValueRef.current` is `null` or any other value if means that the cache does have a value for that key. // This difference between `undefined` and other values is crucial and it's used to address the following // conditions and use cases. newValueRef.current = getCachedValue(key, selectorRef.current); + + // We set this flag to `false` again since we don't want to get the newest cached value every time `getSnapshop()` is executed, + // and only when `Onyx.connect()` callback is fired. + shouldGetCachedValue.current = false; } // Since the fetch status can be different given the use cases below, we define the variable right away. @@ -188,11 +195,14 @@ function useOnyx>(key: T connectionIDRef.current = Onyx.connect({ key, callback: () => { - // We don't need to update the Onyx cache again here, when `callback` is called the cache is already - // expected to be updated, so we just get the new value from cache and signal that the store changed, - // making `getSnapshot()` be called again. + // Signals that the first connection was made, so some logics in `getSnapshot()` + // won't be executed anymore. isFirstConnectionRef.current = false; - newValueRef.current = getCachedValue(key, selectorRef.current); + + // Signals that we want to get the newest cached value again in `getSnapshot()`. + shouldGetCachedValue.current = true; + + // Finally, we signal that the store changed, making `getSnapshot()` be called again. onStoreChange(); }, initWithStoredValues: options?.initWithStoredValues, @@ -208,7 +218,7 @@ function useOnyx>(key: T isFirstConnectionRef.current = false; }; }, - [key, selectorRef, options?.initWithStoredValues], + [key, options?.initWithStoredValues], ); // Mimics withOnyx's checkEvictableKeys() behavior. From 5d3fcc0eed1dc8c4313e7aad1221accbc2bb00f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Henriques?= Date: Wed, 15 May 2024 13:59:59 +0100 Subject: [PATCH 05/11] Add missing comment --- lib/useOnyx.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/useOnyx.ts b/lib/useOnyx.ts index 6ca50347..29d1ee54 100644 --- a/lib/useOnyx.ts +++ b/lib/useOnyx.ts @@ -90,6 +90,7 @@ function useOnyx>(key: T // We initialize it to `undefined` to simulate that we don't have any value from cache yet. const cachedValueRef = useRef | undefined>(undefined); + // Stores the newest cached value in order to compare with the previous one and optimize `getSnapshot()` execution. const newValueRef = useRef | undefined>(undefined); // Stores the previously result returned by the hook, containing the data from cache and the fetch status. From 71d915ef67d77c2a9b875fa37c4e911442770c81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Henriques?= Date: Wed, 15 May 2024 14:06:13 +0100 Subject: [PATCH 06/11] Rename variable --- lib/useOnyx.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/useOnyx.ts b/lib/useOnyx.ts index 624e3867..4c88e8b6 100644 --- a/lib/useOnyx.ts +++ b/lib/useOnyx.ts @@ -84,7 +84,7 @@ function useOnyx>(key: T // Stores the previous cached value as it's necessary to compare with the new value in `getSnapshot()`. // We initialize it to `undefined` to simulate that we don't have any value from cache yet. - const cachedValueRef = useRef | undefined>(undefined); + const previousValueRef = useRef | undefined>(undefined); // Stores the newest cached value in order to compare with the previous one and optimize `getSnapshot()` execution. const newValueRef = useRef | undefined>(undefined); @@ -170,18 +170,18 @@ function useOnyx>(key: T // For the other cases we will only deal with object reference checks, so just a shallow equality check is enough. let areValuesEqual = false; if (OnyxUtils.isCollectionKey(key) && selectorRef.current) { - areValuesEqual = deepEqual(cachedValueRef.current, newValueRef.current); + areValuesEqual = deepEqual(previousValueRef.current, newValueRef.current); } else { - areValuesEqual = shallowEqual(cachedValueRef.current, newValueRef.current); + areValuesEqual = shallowEqual(previousValueRef.current, newValueRef.current); } // If the previously cached value is different from the new value, we update both cached value // and the result to be returned by the hook. if (!areValuesEqual) { - cachedValueRef.current = newValueRef.current; + previousValueRef.current = newValueRef.current; // If the new value is `null` we default it to `undefined` to ensure the consumer get a consistent result from the hook. - resultRef.current = [(cachedValueRef.current ?? undefined) as CachedValue, {status: newFetchStatus ?? 'loaded'}]; + resultRef.current = [(previousValueRef.current ?? undefined) as CachedValue, {status: newFetchStatus ?? 'loaded'}]; } return resultRef.current; From 4889dae85a2dbddee22ac1bb2559c8dc872f4703 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Henriques?= Date: Wed, 15 May 2024 14:07:15 +0100 Subject: [PATCH 07/11] Fix typo --- lib/useOnyx.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/useOnyx.ts b/lib/useOnyx.ts index 4c88e8b6..de87f3c5 100644 --- a/lib/useOnyx.ts +++ b/lib/useOnyx.ts @@ -141,7 +141,7 @@ function useOnyx>(key: T // conditions and use cases. newValueRef.current = getCachedValue(key, selectorRef.current); - // We set this flag to `false` again since we don't want to get the newest cached value every time `getSnapshop()` is executed, + // We set this flag to `false` again since we don't want to get the newest cached value every time `getSnapshot()` is executed, // and only when `Onyx.connect()` callback is fired. shouldGetCachedValue.current = false; } From ddbde4237f612678a268b6d890ad2820af60354d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Henriques?= Date: Wed, 15 May 2024 14:43:46 +0100 Subject: [PATCH 08/11] Fix shouldGetCachedValue typo --- lib/useOnyx.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/useOnyx.ts b/lib/useOnyx.ts index de87f3c5..604f2da1 100644 --- a/lib/useOnyx.ts +++ b/lib/useOnyx.ts @@ -104,7 +104,7 @@ function useOnyx>(key: T const isFirstConnectionRef = useRef(true); // Indicates if we should get the newest cached value from Onyx during `getSnapshot()` execution. - const shouldGetCachedValue = useRef(true); + const shouldGetCachedValueRef = useRef(true); useEffect(() => { // These conditions will ensure we can only handle dynamic collection member keys from the same collection. @@ -134,7 +134,7 @@ function useOnyx>(key: T // We get the value from cache while the first connection to Onyx is being made, // so we can return any cached value right away. After the connection is made, we only // update `newValueRef` when `Onyx.connect()` callback is fired. - if (isFirstConnectionRef.current || shouldGetCachedValue.current) { + if (isFirstConnectionRef.current || shouldGetCachedValueRef.current) { // If `newValueRef.current` is `undefined` it means that the cache doesn't have a value for that key yet. // If `newValueRef.current` is `null` or any other value if means that the cache does have a value for that key. // This difference between `undefined` and other values is crucial and it's used to address the following @@ -143,7 +143,7 @@ function useOnyx>(key: T // We set this flag to `false` again since we don't want to get the newest cached value every time `getSnapshot()` is executed, // and only when `Onyx.connect()` callback is fired. - shouldGetCachedValue.current = false; + shouldGetCachedValueRef.current = false; } // Since the fetch status can be different given the use cases below, we define the variable right away. @@ -197,7 +197,7 @@ function useOnyx>(key: T isFirstConnectionRef.current = false; // Signals that we want to get the newest cached value again in `getSnapshot()`. - shouldGetCachedValue.current = true; + shouldGetCachedValueRef.current = true; // Finally, we signal that the store changed, making `getSnapshot()` be called again. onStoreChange(); From a9421bdcfa990539e7fc50a6e59e4e21836499e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Henriques?= Date: Wed, 22 May 2024 15:49:54 +0100 Subject: [PATCH 09/11] Fix comment --- lib/useOnyx.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/useOnyx.ts b/lib/useOnyx.ts index 604f2da1..5c66cf43 100644 --- a/lib/useOnyx.ts +++ b/lib/useOnyx.ts @@ -9,7 +9,7 @@ import usePrevious from './usePrevious'; /** * Represents a Onyx value that can be either a single entry or a collection of entries, depending on the `TKey` provided. - * It's a variation of `OnyxValue` type that is read-only and excludes the `null` type. + * It's a variation of `OnyxValue` type that excludes the `null` type. */ type UseOnyxValue = string extends TKey ? unknown From bfa096c2669e61b0cd459b188bb307ee454f3e3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Henriques?= Date: Fri, 24 May 2024 19:39:24 +0100 Subject: [PATCH 10/11] Address review comments --- lib/useOnyx.ts | 2 +- tests/unit/useOnyxTest.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/useOnyx.ts b/lib/useOnyx.ts index 5c66cf43..faf3727f 100644 --- a/lib/useOnyx.ts +++ b/lib/useOnyx.ts @@ -168,7 +168,7 @@ function useOnyx>(key: T // since each `OnyxUtils.tryGetCachedValue()` call will generate a plain new collection object with new records as well, // all of them created using the `selector` function. // For the other cases we will only deal with object reference checks, so just a shallow equality check is enough. - let areValuesEqual = false; + let areValuesEqual: boolean; if (OnyxUtils.isCollectionKey(key) && selectorRef.current) { areValuesEqual = deepEqual(previousValueRef.current, newValueRef.current); } else { diff --git a/tests/unit/useOnyxTest.ts b/tests/unit/useOnyxTest.ts index a44ce7c6..eed546f3 100644 --- a/tests/unit/useOnyxTest.ts +++ b/tests/unit/useOnyxTest.ts @@ -195,7 +195,7 @@ describe('useOnyx', () => { expect(result.current[1].status).toEqual('loaded'); }); - it('should not change selected data if a property outside tha data was changed', async () => { + it('should not change selected data if a property outside that data was changed', async () => { Onyx.set(ONYXKEYS.TEST_KEY, {id: 'test_id', name: 'test_name'}); const {result} = renderHook(() => From 24cbaaa825cdb6237706287146efb09e207a054c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Henriques?= Date: Wed, 19 Jun 2024 15:39:05 +0100 Subject: [PATCH 11/11] Update lib/useOnyx.ts Co-authored-by: Vit Horacek <36083550+mountiny@users.noreply.github.com> --- lib/useOnyx.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/useOnyx.ts b/lib/useOnyx.ts index 27ca197a..44d18086 100644 --- a/lib/useOnyx.ts +++ b/lib/useOnyx.ts @@ -175,7 +175,7 @@ function useOnyx>(key: TKey if (isCacheSetFirstTime || !areValuesEqual) { previousValueRef.current = newValueRef.current; - // If the new value is `null` we default it to `undefined` to ensure the consumer get a consistent result from the hook. + // If the new value is `null` we default it to `undefined` to ensure the consumer gets a consistent result from the hook. resultRef.current = [previousValueRef.current as CachedValue, {status: newFetchStatus ?? 'loaded'}]; }