Yew框架中重复绑定同一onclick回调触发Rust E0507移动错误
解决Yew中循环绑定Callback触发的E0507错误
错误原因
在循环渲染多个<input>元素时,直接将add_tag绑定到每个元素的onclick事件会触发编译错误E0507。这是因为yew::Callback未实现Copy trait,每次迭代中使用add_tag都会触发变量移动,而FnMut闭包无法多次移动同一个捕获的变量。
解决方案
yew::Callback实现了Clone trait,只需在每次循环迭代时clone这个Callback,就能避免移动问题。修改循环内的onclick绑定代码即可:
{ for countries.iter().map(|cont| { html!{ <input type="text" class="form-control" readonly=true value={*cont} onclick={add_tag.clone()}/> } })}
修改后的完整代码
use gloo::console::log; use yew::prelude::*; use web_sys::HtmlInputElement; use wasm_bindgen::JsCast; #[function_component(CheckMnemonic)] pub fn check_mnemonic() -> Html { let tags_state: UseStateHandle<Vec<String>> = use_state(||vec![]); let remove_tag = { let tags_state = tags_state.clone(); move |index: usize| { let mut tags = tags_state.to_vec(); tags.remove(index); tags_state.set(tags); } }; let add_tag = Callback::from({ let tags_state = tags_state.clone(); move |event: MouseEvent| { let data = event .target() .unwrap() .unchecked_into::<HtmlInputElement>() .value(); let mut tags = tags_state.to_vec(); tags.push(data.trim().to_owned()); tags_state.set(tags); // 无需clone,直接传递所有权 log!(format!("{:?}", tags)); } }); let countries = vec!["India", "Norway", "Bhutan"]; html! { <> {for tags_state.iter().map(|v| { html! { <p> {v} </p> } })} { for countries.iter().map(|cont| { html!{ <input type="text" class="form-control" readonly=true value={*cont} onclick={add_tag.clone()}/> } })} </> } }
额外优化说明
- 简化
tags_state克隆逻辑:无需提前创建全局克隆,在每个闭包创建时局部clone,代码结构更清晰。 - 移除冗余的
tags.clone():set方法会接管变量所有权,直接传入tags即可,避免不必要的内存拷贝。
内容的提问来源于stack exchange,提问作者Amiya Behera
相关产品推荐
相关产品推荐

