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;
        });
}