-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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 useFrameCallback fast refresh #4121
Conversation
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.
Unfortunately, this PR doesn't work for me even on the most basic example. After fast refresh, no useFrameCallback
callbacks are run.
import React from 'react';
import { View } from 'react-native';
import { useFrameCallback } from 'react-native-reanimated';
export default function AnimatedSensorExample() {
useFrameCallback(() => {
console.log(performance.now());
});
return <View />;
}
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.
I can confirm this change successfully resolves the issue! ✅
Thanks @mstach60161 for this PR!
<!-- Thanks for submitting a pull request! We appreciate you spending the time to work on these changes. Please follow the template so that the reviewers can easily understand what the code changes affect. --> ## Summary This PR fixes the problem of multiple callbacks after fast refresh To prevent multiple loops, we use this if statement ``` // runCallback() should only be called after registering a callback, // so if there is only one active callback, then it means that there were // zero previously and the loop isn't running yet. if (this.activeFrameCallbacks.size === 1) { requestAnimationFrame(loop); } ``` The problem with fast refresh is that we unregister the callback and immediately register new. Before unregistration is completed we register new one, so the previous loop doesn't stop. We also start second loop, because we have one active frame. So in the end, after each fast refresh, we add new loop that execute the same callback. To fix it, I added variable `newCallId` and pass it to each `runCallbacks` call, whenever we delete last item from active callbacks, we increment newCallId variable. Inside `runCallbacks` we check if the function execution is related with the newest `callId`. If not, we stop function execution. ## Test plan - Example app - Flipper
Summary
This PR fixes the problem of multiple callbacks after fast refresh
To prevent multiple loops, we use this if statement
The problem with fast refresh is that we unregister the callback and immediately register new.
Before unregistration is completed we register new one, so the previous loop doesn't stop.
We also start second loop, because we have one active frame. So in the end, after each fast refresh, we add new loop that execute the same callback.
To fix it, I added variable
newCallId
and pass it to eachrunCallbacks
call, whenever we delete last item from active callbacks, we increment newCallId variable. InsiderunCallbacks
we check if the function execution is related with the newestcallId
. If not, we stop function execution.Test plan