-
Notifications
You must be signed in to change notification settings - Fork 579
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
Change listeners on Results should always update React Native UI #2655
Comments
This seems like a duplicate of #2544 to me. Basically Realm listeners fire too early, so any reads you do in the listener can return stale data. |
@thekevinbrown - just reading over #2544, I don't think its the same. |
To be sure I'm following, you're saying that you get correct data in the Realm listener, but when you call setState with that data, the UI doesn't update? And that data is a string? If that's the case it sounds like it's an issue with either React or your component, not a Realm issue. Does the issue stay the same if you remove the
|
Correct.
Yeah - that's just there to show what happens if the thing calling the callback is a timer instead of a Realm change listener.
I suspect it's the combination of the two, perhaps it's rooted in resource throttling / the CPU sleeping. Perhaps Realm JS needs to tell the OS that calling the callback might take more time than it is provided. |
Odd behaviour for sure! What if you change out the setState for more console.log calls? Or like a 10ms setTimeout between console.log calls in a loop? If we can untangle React’s inner workings from this then it puts it much more squarely in Realm’s court, so that’s what I’m trying to see if we can prove. |
Only the first console.log would be printet in the Metro bundler output, but the Safari dev-tools will console log correctly. If you run the code above in a simulator and attach using the Safari dev-tools and make a profiling, you get some very (!!) interesting results. I didn't have the time to dive more into it, but to me it looks like out of order execution of JS is happening 💥, which is probably just a false-positive - perhaps an artifact from how the profiler receives its data from the simulator. |
The more you talk about this the more I think it’s the same as the issue I logged. I’ll see if I can dig into your example more. |
Have you tried something like |
@fealebenpae, in my repro on the other issue you can fix it with a I would argue that it's Realm's job to ensure the write is persisted enough that reads will show the new data before calling a listener. @kneth said that this behaviour was a feature, not a bug, and that this way the UI updates faster. (Except it unfortunately doesn't because although the render is called more quickly, the data doesn't show on the screen, and we never get a notification when the data is 'really' there, so the listener ends up producing a UI that's buggy and doesn't show the data that's actually in the DB, it shows what was there before the write that's causing the re-render in the first place.) |
Is there any update on this issue? Apple has rejected my app for this bug. |
@aureliopetrone Can you explain why it was rejected due to this? |
@kneth I use this code for displaying a spinner while the app synchronize my initial data from a query-synched realm. The problem is that since the promises are not resolved until I tap the screen the loading process seems infinite and the spinner doesn't go out.
So I guess the problem is not only with Results listeners but also with subscription ones. |
@kneth @kraenhansen @ericjordanmossman |
This is my solution to refresh the data and rerender the UI.
|
Thank you! This isn't how it should work, but it definitely worked when I followed your pattern. |
I'm seeing the same issue randomly on iOS. Can anyone summarize what's the problem exactly and the best work-around? This seems like an IOS only problem, but basically, any setTimeout call stops working randomly for a few seconds or until the UI is touched when fired within a callback/listener. For example, I have the following code: Helper method to make all realm calls "async" (not really, but makes it awaitable and doesn't freeze the UI)
Listener setup
Actual handler:
|
It is possible usage of |
What's the status of this? I'm seeing this with |
@cristianoccazinsp Sorry for the late response here, I didn't see your comment originally, but this should be fixed in new releases. Please let us know if you think you see it occurring still |
@tomduncalf thanks for the update, we will give it a try soon. |
Goals
A callback registered as a listener for changes on a Realm JS
Results
instance should always be able to trigger updates of the React Native UI.Expected Results
From a React Native app, when registering a callback on a
Results
object and callingthis.setState
on a component, I would expect the UI to always update.Actual Results
this.setState
is the first method called in the callback.Steps to Reproduce & Code Sample
Initialize a new React Native app:
Copy in the files below, install the dependencies
Create an instance of ROS and update
constants.js
.In one terminal, start the updater (a node process changing a realm every second) - in another start the app on iOS
The app has two modes: "interval" where a timer will update the state every second and "realm" where a change listener will be registered and the bug is observed.
Use the Safari developer tools to attach to the apps JSContext and observe the issue in the timeline:
// TODO: Add images of the timeline and call-stacks when running in the two modes.
package.json
App.js
constants.js
schema.js
updater/index.js
Version of Realm and Tooling
The text was updated successfully, but these errors were encountered: