Dioxus框架中(use_resource)

225 阅读1分钟

资源(Resource)

use_resource允许你运行一个异步闭包,并提供其结果。

例如,我们可以在use_resource内部进行API请求(使用reqwest):

let mut future = use_resource(|| async move {
    reqwest::get("https://dog.ceo/api/breeds/image/random")
        .await
        .unwrap()
        .json::<ApiResponse>()
        .await
});

use_resource内部的代码将在组件渲染后提交给Dioxus调度器。

我们可以使用.read()来获取未来的结果。在第一次运行时,由于组件加载时没有准备好的数据,其值将为None。然而,一旦未来完成,组件将重新渲染,值将变为Some(...),包含闭包的返回值。

然后,我们可以渲染该结果:

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)

Resource句柄提供了一个restart方法。它可以用来再次执行未来,产生一个新值。

依赖关系(Dependencies)

通常,你需要在某个值(例如状态)变化时再次运行未来。你可以在未来内部读取一个信号,而不是手动调用restart。当你在未来内部读取的任何状态发生变化时,它将自动重新运行未来。示例:

let future = use_resource(move || async move {
    reqwest::get(format!("https://dog.ceo/api/breed/{breed}/images/random"))
        .await
        .unwrap()
        .json::<ApiResponse>()
        .await
});

// 你还可以通过use_reactive方法向资源钩子添加非反应性状态
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
}));

img