-
Notifications
You must be signed in to change notification settings - Fork 563
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix #4513 #4519
Fix #4513 #4519
Conversation
Realm welcomes all contributions! The only requirement we have is that, like many other projects, we need to have a Contributor License Agreement (CLA) in place before we can accept any external code. Our own CLA is a modified version of the Apache Software Foundation’s CLA. Our records show that CLA has not been signed by @mfbx9da4. Please submit your CLA electronically using our Google form so we can accept your submissions. After signing the CLA you can recheck this PR with a |
I didn't spend too long on this so might need some tweaking or cleaning up? @takameyer This won't fix the fact that:
(as mentioned in #4513). I imagine the code will have to change significantly to solve these latter two issues so not sure this commit is super useful. |
@mfbx9da4 Thanks for the PR! Slightly different take than my idea: return function useObject<T>(type: string | { new (): T }, primaryKey: PrimaryKey): (T & Realm.Object) | null {
const realm = useRealm();
// Create a forceRerender function for the cachedObject to use as its updateCallback, so that
// the cachedObject can force the component using this hook to re-render when a change occurs.
const [version, forceRerender] = useReducer((x) => x + 1, 0);
// 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,
}),
[type, realm, primaryKey],
);
// Invoke the tearDown of the cachedObject when useObject is unmounted
useEffect(() => {
return tearDown;
}, [tearDown]);
return useMemo(() => {
// If the object has been deleted or doesn't exist for the given primary key, just return null
if (object === null || object?.isValid() === false) {
return null;
} else {
// Wrap object in a proxy to update the reference on rerender ( should only rerender when something has changed )
return new Proxy(object, {});
}
// We need version as a dependency in order to trigger a new object reference
}, [version, object]);
}; We will need to write a test case for this and the other issues in order to avoid regressions. |
Yeah cool! I like your way of doing it. It would be cleaner IMO if the cached object API was tweaked though function useObject<T>(type: string | { new (): T }, primaryKey: PrimaryKey): (T & Realm.Object) | null {
const realm = useRealm()
const cachedObject = useMemo<(T & Realm.Object) | null>(
() => createCachedObject(realm, type, primaryKey),
[realm, type, primaryKey]
)
const [version, setVersion] = useState(0)
useEffect(() => {
return cachedObject?.subscribe(() => setVersion(x => x + 1))
}, [cachedObject])
return useMemo(() => cachedObject.object ? new Proxy(cachedObject.object : null, {}), [cachedObject, version])
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like we need to rebase and write a regression test. If you got some time to do that, we would be very grateful 🙂
Otherwise it may be some time before I get to it.
Adding @tomduncalf and @kraenhansen to the review as well |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code looks great, but I would like to see a regression test in both useQueryRender
and useObjectRender
that verifies that this fix works. Functionally it should trigger a re-render on the parent component (using useState
) and verify that the children were not re-rendered.
It also appears this needs to rebase with master.
And please add an entry to the packages/realm-react/CHANGELOG.md
🙂
Co-authored-by: Andrew Meyer <andrew.meyer@mongodb.com>
Co-authored-by: Andrew Meyer <andrew.meyer@mongodb.com>
I've squashed the current changes into a single commit and am continuing this PR on my own here: |
What, How & Why?
Fixes #4513 and #4913