如何在Yew Hook中返回状态的字符串值?解决use_effect_with_deps报错
解决Yew自定义Hook中所有权相关编译错误
原问题代码
use std::ops::Deref; use yew::prelude::*; #[hook] pub fn use_hook_test() -> String { let first_load = use_state(|| true); let hash_state = use_state(|| "".to_owned()); let hash_state_clone = hash_state.clone(); use_effect_with_deps(move |_| { if *first_load { wasm_bindgen_futures::spawn_local(async move { hash_state_clone.set(format!("{:?}", "Hello")); }); first_load.set(false); } || {}; }, ()); hash_state_clone.deref().clone() }
编译报错信息
let hash_state_clone = hash_state.clone(); | ---------------- move occurs because `hash_state_clone` has type `yew::UseStateHandle<std::string::String>`, which does not implement the `Copy` trait 14 | use_effect_with_deps(move |_| { | -------- value moved into closure here ... 18 | hash_state_clone.set(format!("{:?}", "Hello")); | ---------------- variable moved due to use in closure ... 27 | hash_state_clone.deref().clone() | ^^^^^^^^^^^^^^^^^^^^^^^^ value borrowed here after move
解决方案及修正代码
问题核心是hash_state_clone被移动进use_effect_with_deps的闭包后,所有权已转移,无法在闭包外继续使用。我们需要为闭包单独克隆状态句柄,避免所有权冲突:
use std::ops::Deref; use yew::prelude::*; #[hook] pub fn use_hook_test() -> String { let first_load = use_state(|| true); let hash_state = use_state(|| "".to_owned()); // 为effect闭包单独克隆状态句柄,让闭包拥有独立所有权 let hash_state_effect = hash_state.clone(); let first_load_effect = first_load.clone(); use_effect_with_deps(move |_| { if *first_load_effect { wasm_bindgen_futures::spawn_local(async move { hash_state_effect.set(format!("{:?}", "Hello")); }); first_load_effect.set(false); } || {} }, ()); // 直接基于原状态句柄返回字符串克隆,无所有权问题 hash_state.deref().clone() }
关键说明
UseStateHandle是基于Arc实现的轻量句柄,克隆操作几乎无性能开销,无需担心重复克隆的问题。- 为闭包单独克隆
first_load_effect是因为原first_load属于当前渲染周期的变量,闭包需要拥有自己的句柄才能在异步操作中安全访问。 - 返回部分也可以简化为
(**hash_state).clone()或hash_state.to_string(),效果完全一致。
内容的提问来源于stack exchange,提问作者Amiya Behera
相关产品推荐
相关产品推荐

