use_effect blocks UI updates? #1827
-
Maybe I'm misunderstanding something about how to properly perform long-running tasks without blocking the UI; however, I'm running into some issues with something similar to the following: fn WhyBlockingEffect(cx: Scope) -> Element {
let token = use_state(cx, || None);
use_effect(cx, (token,), |(token,)| {
to_owned![token];
async move {
// Background task, might take a long time to complete.
if token.get().is_some() {
std::thread::sleep(Duration::from_secs(5));
token.set(None);
}
}
});
let status_text = format!("Is thinking: {}", token.get().is_some());
eprintln!("Should be rendering: {}", status_text);
cx.render(rsx! {
button {
onclick: |_| {
token.set(Some("value"));
},
"Button"
},
div {
status_text
}
})
} With the above component (representative of a more complex component I'm working on), when the button is clicked, the console prints out the expected text immediately, and after the 5-second delay does so again with the expected output. The problem is, the UI doesn't reflect this; instead, it seizes up until after the async code has finished execution. This is occurring with a hot-reload in desktop mode. Any advice or other suggestions would be appreciated. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
Dioxus runs async tasks on the main thread by default. If you want to run an expensive task you can use another thread or a tokio task. If your real task is blocking, I would recommend using a new thread. If you change the task in your example to be async, it should work: fn WhyBlockingEffect(cx: Scope) -> Element {
let token = use_state(cx, || None);
use_effect(cx, (token,), |(token,)| {
to_owned![token];
async move {
// Background task, might take a long time to complete.
if token.get().is_some() {
tokio::time::sleep(Duration::from_secs(5)).await;
token.set(None);
}
}
});
let status_text = format!("Is thinking: {}", token.get().is_some());
eprintln!("Should be rendering: {}", status_text);
cx.render(rsx! {
button {
onclick: |_| {
token.set(Some("value"));
},
"Button"
},
div {
status_text
}
})
} |
Beta Was this translation helpful? Give feedback.
Dioxus runs async tasks on the main thread by default. If you want to run an expensive task you can use another thread or a tokio task.
If your real task is blocking, I would recommend using a new thread. If you change the task in your example to be async, it should work: