dioxus
dioxus copied to clipboard
Async closures does not work with event handlers
Problem
Steps To Reproduce
use dioxus::prelude::*;
#[server]
async fn save_dog(image: String) -> Result<(), ServerFnError> {
Ok(())
}
#[component]
fn DogView() -> Element {
let src = use_signal(|| "https://images.dog.ceo/breeds/pitbull/dog-3981540_1280.jpg");
let save = async move |_| {
save_dog(src.cloned().to_owned()).await.unwrap();
};
rsx! {
img { src }
div {
button { onclick: save, "save!" }
}
}
}
Error:
error: async closure does not implement `FnMut` because it captures state from its environment
--> src/main.rs:104:16
|
104 | let save = async move |_| {
| ^^^^^^^^^^^^^^
...
113 | button { onclick: save, "save!" }
| ------------- required by a bound introduced by this call
|
= note: required for `Callback<dioxus::prelude::Event<MouseData>>` to implement `SuperFrom<{async closure@src/main.rs:104:16: 104:30}, MarkerWrapper<dioxus::dioxus_core::events::AsyncMarker>>`
= note: required for `{async closure@src/main.rs:104:16: 104:30}` to implement `SuperInto<Callback<dioxus::prelude::Event<MouseData>>, MarkerWrapper<dioxus::dioxus_core::events::AsyncMarker>>`
But it works when you use an inner async block instead:
- let save = async move |_| {
+ let save = move |_| async move {
save_dog(src.cloned().to_owned()).await.unwrap();
};
Expected behavior
Async closures has been stabilized, so it should be expected that it works with Dioxus.
Screenshots
Environment:
- Dioxus version: v0.6.0
- Rust version: v1.85.0-nightly (45d11e51b 2025-01-01)
- OS info: Linux
- App platform:
web
Questionnaire
Async closures are still unstable and can only be used in the nightly edition of rust. Dioxus could accept async closures, but all of the async closure logic would need to be gated under the nightly version of rust
Now that Rust 1.85 and Edition 2024 have been released with async closures stabilized. I think it's time to revisit this.