【问题标题】:Show input value in browser using Yew Rust使用 Yew Rust 在浏览器中显示输入值
【发布时间】:2023-02-05 14:00:36
【问题描述】:

我开始用 Yew 学习 Rust。我遵循了文档中的反例,现在我正在尝试实现输入功能。我想在 html 中显示输入值。我能够 console.log 但不能在浏览器中呈现它。

我错过了什么?

这是我到目前为止的代码:

use wasm_bindgen::{JsCast, UnwrapThrowExt};
use web_sys::HtmlInputElement;
use yew::prelude::*;

#[function_component]
fn App() -> Html {
    let name = use_state(|| "");
    let oninput = Callback::from(move |input_event: InputEvent| {
        let name = name.clone();
        let target: HtmlInputElement = input_event
            .target()
            .unwrap_throw()
            .dyn_into()
            .unwrap_throw();
        //web_sys::console::log_1(&target.value().into()); // <- can console the value.
        move |_: HtmlInputElement| name.set(&target.value().as_str());
    });

    html! {
        <div>
            <input {oninput}  />
            <p>{"name: "}<h5>{name}</h5></p> // <-- here is the error
        </div>
    }
}

fn main() {
    yew::Renderer::<App>::new().render();
}

但我收到此错误:

error[E0277]: `UseStateHandle<&str>` doesn't implement `std::fmt::Display`
  --> src/main.rs:22:29
   |
22 |             <p>{"name"}<h5>{name}</h5></p>
   |                             ^^^^
   |                             |
   |                             `UseStateHandle<&str>` cannot be formatted with the default formatter
   |                             required by a bound introduced by this call
   |
   = help: the trait `std::fmt::Display` is not implemented for `UseStateHandle<&str>`
   = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
   = note: required for `UseStateHandle<&str>` to implement `ToString`
   = note: required for `VNode` to implement `From<UseStateHandle<&str>>`
   = note: required for `UseStateHandle<&str>` to implement `Into<VNode>`
   = note: 2 redundant requirements hidden
   = note: required for `UseStateHandle<&str>` to implement `Into<NodeSeq<UseStateHandle<&str>, VNode>>`

我尝试使用 name.get()&amp;namename.clone() 以及它们的组合,但我总是遇到错误。你能解释一下为什么我无法在浏览器中显示值吗?

我感谢任何帮助。

【问题讨论】:

  • 请发布来自cargo check(不是您的 IDE)的完整错误。
  • @ChayimFriedman 我用货物检查的输出更新了错误消息。谢谢。

标签: rust yew


【解决方案1】:

要使用状态中的值,您需要取消引用它:

<p>{"name: "}<h5>{*name}</h5></p>

但是,现在您将看到另一个错误:

error[E0716]: temporary value dropped while borrowed
  --> src/main.rs:23:46
   |
16 |         let name = name.clone();
   |             ---- lifetime `'1` appears in the type of `name`
...
23 |         move |_: HtmlInputElement| name.set(&target.value().as_str());
   |                                    ----------^^^^^^^^^^^^^^----------
   |                                    |         |                      |
   |                                    |         |                      temporary value is freed at the end of this statement
   |                                    |         creates a temporary value which is freed while still in use
   |                                    argument requires that borrow lasts for `'1`

error[E0382]: borrow of moved value: `name`
   --> src/main.rs:29:31
    |
14  |     let name = use_state(|| "");
    |         ---- move occurs because `name` has type `UseStateHandle<&str>`, which does not implement the `Copy` trait
15  |     let oninput = Callback::from(move |input_event: InputEvent| {
    |                                  ------------------------------ value moved into closure here
16  |         let name = name.clone();
    |                    ---- variable moved due to use in closure
...
29  |             <p>{"name: "}<h5>{*name}</h5></p> // <-- here is the error
    |                               ^^^^^ value borrowed here after move
    |
    = note: borrow occurs due to deref coercion to `&str`
note: deref defined here
   --> /home/explorer/.cargo/registry/src/github.com-1ecc6299db9ec823/yew-0.20.0/src/functional/hooks/use_state.rs:128:5
    |
128 |     type Target = T;
    |     ^^^^^^^^^^^

第一个错误是因为您需要存储String 而不是&amp;str。第二个是因为你需要clone()状态关闭:

#[function_component]
fn App() -> Html {
    let name = use_state(|| String::new());
    let oninput = Callback::from({
        let name = name.clone();
        move |input_event: InputEvent| {
            let target: HtmlInputElement = input_event
                .target()
                .unwrap_throw()
                .dyn_into()
                .unwrap_throw();
            //web_sys::console::log_1(&target.value().into()); // <- can console the value.
            name.set(target.value());
        }
    });

    html! {
        <div>
            <input {oninput}  />
            <p>{"name: "}<h5>{&*name}</h5></p>
        </div>
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-03
    • 1970-01-01
    • 1970-01-01
    • 2023-02-23
    • 1970-01-01
    • 2016-12-18
    • 2012-08-05
    相关资源
    最近更新 更多