-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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(event): clear residual js listeners (#8916 ) #8930
fix(event): clear residual js listeners (#8916 ) #8930
Conversation
fixed.mp4The origin error demo can be seen at #8916 |
e422726
to
ff5c8de
Compare
I think there's a better way to do this. Handling this via a command called by the frontend might lead to race conditions. |
e1109ec
to
3fb414b
Compare
…ners merge `Test on page load clear js listeners` into default
Very good suggestion, I hadn't thought of fixing this bug here before, and now that I've rewritten a new version which doesn't involve any front-end code and no more demo.mp4 |
Been using this for today's development and had no issues at all :) |
Thank you |
I'm not sure if this is expected, but this change seems to be causing some kind of race condition on initial load of a React page. I am calling
I am new to Tauri, so I may be doing something wrong, but is this expected? |
Hmm, i highly doubt that componentDidMount triggers before DOMContentLoaded. Not 100% sure but still feels wrong to me. Can you share the code where you listen to and emit the event? |
It's closed-source, but let me try to reduce it to something minimal. While I work on that, could you point me to any advice or best practices for places in the lifecycle of a React page where it makes the most sense to set up event listening? |
componentDidMount or useEffect with [] is indeed correct. You just have to unlisten to the event on unmount too. An example for that with useEffect (because i didn't use componentDidMount for years) looks like this useEffect(() => {
const unlisten = listen("someevent", console.log);
return () => {
unlisten.then( f => f() );
}
}, []); |
In making my minimal reproducer I realized I had several incorrect assumptions about my code. I think things are working now. Apologies for the spam. |
Here's a repro demonstrating a bug where the listeners are cleaned up too late, destroying new callbacks that were just installed. For me, this works on Windows and on MacOS dev builds, but fails on MacOS production builds. |
…ered ids to be triggerd fix regression introduced in #8930 , and reported in #8930 (comment)
…filtered ids to be triggered (#9151) * fix(core/event): filter js listeners on rust side only then emit filtered ids to be triggerd fix regression introduced in #8930 , and reported in #8930 (comment) * Update .changes/core-js-unlisten-all-regression.md Co-authored-by: Lucas Fernandes Nogueira <[email protected]> * Discard changes to .changes/core-js-unlisten-all-regression.md * object.defineproperty * add change file [skip ci] --------- Co-authored-by: Lucas Fernandes Nogueira <[email protected]>
fix clear residual listeners, close #8916
I noticed that in v1,
js_listeners
were stored on the frontend, so refreshing the page cleans up the originaljs_listeners
(note that this doesn't mean that useEffect cleans up the side-effects, as it doesn't have a way to clean up the side-effects before refreshing the page).However, in v2,
js_listeners
are stored not only in the front end, but also in the back end, and the number of events triggered is determined by thejs_listeners
that stored in the backend, which results in a pileup ofjs_listeners
that can't be cleaned up when the page is refreshed.I added a new js command
unlisten_all
and invoke it at the end ofcore.js
to solve this problem.unlisten_all
only cancels thejs_listeners
at the frontend and backend of the current window.This fix works fine on my machine, in both single-window and multi-window scenarios.