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