Realm slows down app performance when updating multiple screen with react-navigation/native
Problem
here is a discussion about the problem - https://github.com/realm/realm-js/discussions/6490 Is there a solution to prevent useQuery from re-rendering a screen that you're not currently on? If so, could you please provide an example?
Solution
Whenever you trigger an update in Realm, useQuery gets updated, causing every screen in the bottom tab that uses useQuery to re-render. Is there a way to prevent this, so it only triggers a re-render when you visit that screen, and only if there was an update?
Alternatives
No response
How important is this improvement for you?
Would be a major improvement
Feature would mainly be used with
Local Database only
Yhea we had to use enableFreeze() (https://github.com/react-navigation/react-navigation/discussions/11241)
Hi @shanoysinc , Has this issue been resolved? I'm very interested in knowing if there's a solution. If you get any solution Please let me know!
Thank you!
Yhea we had to use enableFreeze() (react-navigation/react-navigation#11241)
when freeze is enabled, animations stop working.
Hi @shanoysinc , Has this issue been resolved? I'm very interested in knowing if there's a solution. If you get any solution Please let me know!
Thank you!
This was the solution I came up with. There's lots of room for improvement, but how it works is that Realm will only update the state when the screen is in focus. I only use this hook for screens that are in the bottom tab navigation.
`
import { useFocusEffect } from "@react-navigation/native";
import { useCallback, useMemo, useRef, useState } from "react";
import { Realm } from "@realm/react";
export const useRealmQuery = <T extends object>(
realm: Realm,
objectType: string,
filterQuery: string | null
) => {
const result: any = useMemo(() => {
if (filterQuery) {
return realm.objects<T>(objectType).filtered(filterQuery);
}
return realm.objects<T>(objectType);
}, [objectType, filterQuery]);
const [data, setData] = useState<Realm.Results<T>>(result);
const init = useRef(true);
useFocusEffect(
useCallback(() => {
const updateState = () => {
if (init.current) {
init.current = false;
return;
}
let newData: any;
if (filterQuery) {
newData = realm.objects<T>(objectType).filtered(filterQuery);
} else {
newData = realm.objects<T>(objectType);
}
setData(newData);
};
const listener = () => updateState();
result.addListener(listener);
return () => {
result.removeListener(listener);
};
}, [filterQuery]) // Only re-run if these dependencies change
);
return data;
};
`
usage
const realm = useRealm();
const tasks = useRealmQuery<Task>(
realm,
"Task",
`archived != true`
);
If anyone manages to improve the above implementation please let me know