Spawning Futures
The use_future
and use_coroutine
hooks are useful if you want to unconditionally spawn the future. Sometimes, though, you'll want to only spawn a future in response to an event, such as a mouse click. For example, suppose you need to send a request when the user clicks a "log in" button. For this, you can use cx.spawn
:
#![allow(unused)] fn main() { let logged_in = use_state(cx, || false); let log_in = move |_| { cx.spawn({ let logged_in = logged_in.to_owned(); async move { let resp = reqwest::Client::new() .post("http://example.com/login") .send() .await; match resp { Ok(_data) => { println!("Login successful!"); logged_in.set(true); } Err(_err) => { println!( "Login failed - you need a login server running on localhost:8080." ) } } } }); }; cx.render(rsx! { button { onclick: log_in, "Login", } }) }
Note:
spawn
will always spawn a new future. You most likely don't want to call it on every render.
Calling spawn
will give you a JoinHandle
which lets you cancel or pause the future.
Spawning Tokio Tasks
Sometimes, you might want to spawn a background task that needs multiple threads or talk to hardware that might block your app code. In these cases, we can directly spawn a Tokio task from our future. For Dioxus-Desktop, your task will be spawned onto Tokio's Multithreaded runtime:
#![allow(unused)] fn main() { cx.spawn(async { let _ = tokio::spawn(async {}).await; let _ = tokio::task::spawn_local(async { // some !Send work }) .await; }); }