Resource
use_resource
lets you run an async closure, and provides you with its result.
For example, we can make an API request (using reqwest) inside use_resource
:
let mut future = use_resource(|| async move { reqwest::get("https://dog.ceo/api/breeds/image/random") .await .unwrap() .json::<ApiResponse>() .await });
The code inside use_resource
will be submitted to the Dioxus scheduler once the component has rendered.
We can use &*future.read_unchecked()
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:
match &*future.read_unchecked() { 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 Resource
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 state) changes. Rather than calling restart
manually, you can read a signal inside of the future. It will automatically re-run the future when any of the states you read inside the future change. Example:
let future = use_resource(move || async move { reqwest::get(format!("https://dog.ceo/api/breed/{breed}/images/random")) .await .unwrap() .json::<ApiResponse>() .await }); // You can also add non-reactive state to the resource hook with the use_reactive method let non_reactive_state = "poodle"; use_resource(use_reactive!(|(non_reactive_state,)| async move { reqwest::get(format!( "https://dog.ceo/api/breed/{non_reactive_state}/images/random" )) .await .unwrap() .json::<ApiResponse>() .await }));