UseFuture

use_future lets you run an async closure, and provides you with its result.

For example, we can make an API request (using reqwest) inside use_future:


#![allow(unused)]
fn main() {
let future = use_future(cx, (), |_| async move {
    reqwest::get("https://dog.ceo/api/breeds/image/random")
        .await
        .unwrap()
        .json::<ApiResponse>()
        .await
});
}

The code inside use_future will be submitted to the Dioxus scheduler once the component has rendered.

We can use .value() to get the result of the future. On the first run, since there's no data ready when the component loads, its value will be None. However, once the future is finished, the component will be re-rendered and the value will now be Some(...), containing the return value of the closure.

We can then render that result:


#![allow(unused)]
fn main() {
cx.render(match future.value() {
    Some(Ok(response)) => rsx! {
        button {
            onclick: move |_| future.restart(),
            "Click to fetch another doggo"
        }
        div {
            img {
                max_width: "500px",
                max_height: "500px",
                src: "{response.image_url}",
            }
        }
    },
    Some(Err(_)) => rsx! { div { "Loading dogs failed" } },
    None => rsx! { div { "Loading dogs..." } },
})
}

Restarting the Future

The UseFuture handle provides a restart method. It can be used to execute the future again, producing a new value.

Dependencies

Often, you will need to run the future again every time some value (e.g. a prop) changes. Rather than calling restart manually, you can provide a tuple of "dependencies" to the hook. It will automatically re-run the future when any of those dependencies change. Example:


#![allow(unused)]
fn main() {
let future = use_future(cx, (breed,), |(breed,)| async move {
    reqwest::get(format!("https://dog.ceo/api/breed/{breed}/images/random"))
        .await
        .unwrap()
        .json::<ApiResponse>()
        .await
});
}