如何使用max来比较Dioxus的use_state?



我目前正在使用Dioxus生成一个动态更改图像轮询器的页面。

我现在想要实现的是使用max函数来比较use_state的结果,以防止数字低于1。

这是一个简单的应用程序:


use dioxus::{events::*, hooks::UseState, prelude::*};
use log::{info, LevelFilter};
use std::cmp::{max, Ordering};
impl PartialOrd for UseState<i32> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for UseState<i32> {
fn cmp(&self, other: &Self) -> Ordering {
self.x.cmp(&other.x)
}
}
/**
* Specify <link data-trunk rel="copy-dir" href="src/assets" />
* in the index.html to copy the files!!
*
* You'll see them in the dist directory!
*/
fn main() {
dioxus_logger::init(LevelFilter::Info).expect("failed to init logger");
dioxus::web::launch(app);
}
fn app(cx: Scope) -> Element {
let mut index = use_state(&cx, || 1);
let val = index.get() as &i32;
let num = 1 as i32;
let change_evt = move |evt: KeyboardEvent| match evt.key.as_str() {
"ArrowRight" => index += 1,
"ArrowLeft" => index = max(&num.try_into(), &val.try_into()),
_ => {}
};
let url = format!("/assets/manga/one_piece/1042/0{}.jpg", index);
cx.render(rsx!(img {
src: "{url}",
}
div {
class: "display",
onkeydown: change_evt,
button {
class: "but",
onclick: move |evt| {
println!("{evt:?}");
info!("{evt:?}");
},
"Press me!"
},
},
))
}

一开始我认为使用index.get()会得到与max()比较所需的i32

但是它抱怨并告诉我我需要为UseState{Integer}实现PartialOrd

我目前正试图实现它。

这是我的cargo.toml

[package]
name = "rust-manga"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
dioxus = { version = "0.2.4", features = ["web", "html"] }
dioxus-html = "0.2.1"
dioxus-logger = "0.3.0"
log = "0.4.17"

当为某些东西(如impl PartialOrd for UseState)实现trait时,那么两个组件中至少有一个必须属于定义impl的crate。但是PartialOrdUseState都是在您的crate之外定义的,所以您不能这样做。

有两个选项:

  1. 一个属于你的板条箱的新类型,这样你就可以在上面实现特征:
struct MyUseState<T: 'static>(UseState<T>);
impl<T> PartialOrd for MyUseState<T> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
todo!();
}
}

缺点是您需要在自定义类型中包装使用dioxus::hooks::UseState的实例,至少当您想比较事物时。

  1. 使用UseState提供的方法:

如果UseState没有实现传递给std::cmp::max所需的特征,我们必须获得内部值。它确实提供了多种方法来做到这一点,例如UseState::get(),UseState::current()Deref的实现。

我们可以做max(num, *index.get()),其中.get()得到一个&i32,我们引用它来得到值。或max(num, **index),使用Deref

然而,我们仍然不能把它赋值给index,因为i32不能赋值给UseState

这就是UseState::modify()的作用。它允许您就地修改值:

// Again, `.modify()` only gives a reference to the closure, which we have to derefence.
index.modify(|val| max(num, *val))

最新更新