Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
mfbx9da4 committed Apr 22, 2022
1 parent f02968c commit 8484abf
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 13 deletions.
24 changes: 17 additions & 7 deletions packages/realm-react/src/useObject.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
//
////////////////////////////////////////////////////////////////////////////
import Realm from "realm";
import { useEffect, useReducer, useMemo } from "react";
import { useEffect, useReducer, useMemo, useRef } from "react";
import { createCachedObject } from "./cachedObject";

// In order to make @realm/react work with older version of realms
Expand Down Expand Up @@ -52,15 +52,26 @@ export function createUseObject(useRealm: () => Realm) {
// the cachedObject can force the component using this hook to re-render when a change occurs.
const [, forceRerender] = useReducer((x) => x + 1, 0);

const objectRef = useRef<Realm.Object & T | null>(null);

// Wrap the cachedObject in useMemo, so we only replace it with a new instance if `primaryKey` or `type` change
const { object, tearDown } = useMemo(
// TODO: There will be an upcoming breaking change that makes objectForPrimaryKey return null
// When this is implemented, remove `?? null`
() =>
createCachedObject({
object: realm.objectForPrimaryKey(type, primaryKey) ?? null,
updateCallback: forceRerender,
}),
{
const updateCallback = () => {
// Wrap object in a proxy to update the reference on rerender ( should only rerender when something has changed )
objectRef.current = cachedObject.object ? new Proxy(cachedObject.object, {}) : null;
forceRerender();
}
const cachedObject = createCachedObject({
object: realm.objectForPrimaryKey(type, primaryKey) ?? null,
updateCallback: forceRerender,
})
objectRef.current = cachedObject.object;
return cachedObject
},
[type, realm, primaryKey],
);

Expand All @@ -74,7 +85,6 @@ export function createUseObject(useRealm: () => Realm) {
return null;
}

// Wrap object in a proxy to update the reference on rerender ( should only rerender when something has changed )
return new Proxy(object, {});
return objectRef.current
};
}
22 changes: 16 additions & 6 deletions packages/realm-react/src/useQuery.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
////////////////////////////////////////////////////////////////////////////

import Realm from "realm";
import { useEffect, useReducer, useMemo } from "react";
import { useEffect, useMemo, useRef, useReducer } from "react";
import { createCachedCollection } from "./cachedCollection";

/**
Expand Down Expand Up @@ -53,10 +53,22 @@ export function createUseQuery(useRealm: () => Realm) {
// Create a forceRerender function for the cachedCollection to use as its updateCallback, so that
// the cachedCollection can force the component using this hook to re-render when a change occurs.
const [, forceRerender] = useReducer((x) => x + 1, 0);
const collectionRef = useRef({} as Realm.Results<T & Realm.Object>);

// Wrap the cachedObject in useMemo, so we only replace it with a new instance if `primaryKey` or `type` change
const { collection, tearDown } = useMemo(
() => createCachedCollection({ collection: realm.objects(type), updateCallback: forceRerender }),
const { tearDown } = useMemo(
() => {
const updateCallback = () => {
// This makes sure the collection has a different reference on a rerender
// Also we are ensuring the type returned is Realm.Results, as this is known in this context
collectionRef.current = new Proxy(cachedCollection.collection as Realm.Results<T & Realm.Object>, {})
forceRerender()
}
const cachedCollection = createCachedCollection({ collection: realm.objects(type), updateCallback });
collectionRef.current = cachedCollection.collection as Realm.Results<T & Realm.Object>
return cachedCollection

},
[type, realm],
);

Expand All @@ -65,8 +77,6 @@ export function createUseQuery(useRealm: () => Realm) {
return tearDown;
}, [tearDown]);

// This makes sure the collection has a different reference on a rerender
// Also we are ensuring the type returned is Realm.Results, as this is known in this context
return new Proxy(collection as Realm.Results<T & Realm.Object>, {});
return collectionRef.current;
};
}

0 comments on commit 8484abf

Please sign in to comment.