如何在Yew中为多个元素复用Callback而无需克隆
无需克隆即可复用Yew回调的方法
你遇到的问题是因为第一个按钮的move闭包把onclick回调的所有权移走了,导致第二个按钮没法再使用它。下面给你两种不用克隆原回调的解决思路:
思路一:为每个按钮创建专属回调
直接针对每个按钮的路由创建独立的回调,不用先封装成通用的:
#[function_component] pub fn Navbar() -> Html { let navigator = use_navigator().unwrap(); // 直接生成对应Home和Scores页面的点击回调 let onclick_home = Callback::from(move |_| navigator.push(&Route::Home)); let onclick_scores = Callback::from(move |_| navigator.push(&Route::Scores)); html! { <nav class="bg-indigo-700 flex justify-between items-center mx-auto max-w p-3"> <div> <h1 class="text-gray-50 font-bold text-2xl">{"Arithmetic Booster"}</h1> </div> <div class="flex space-x-2"> <button class="text-gray-50 bg-indigo-600 p-2 rounded-md" onclick={onclick_home}>{"Play"}</button> <button class="text-gray-50 bg-indigo-600 p-2 rounded-md" onclick={onclick_scores}>{"Scores"}</button> <button class="text-gray-50 bg-red-600 p-2 rounded-md">{"Quit"}</button> </div> </nav> } }
思路二:直接在按钮的onclick中操作导航器
不用提前封装回调,直接在每个按钮的点击事件里调用navigator.push,只需要在第一个按钮里克隆导航器(导航器本身的克隆成本极低):
#[function_component] pub fn Navbar() -> Html { let navigator = use_navigator().unwrap(); html! { <nav class="bg-indigo-700 flex justify-between items-center mx-auto max-w p-3"> <div> <h1 class="text-gray-50 font-bold text-2xl">{"Arithmetic Booster"}</h1> </div> <div class="flex space-x-2"> <button class="text-gray-50 bg-indigo-600 p-2 rounded-md" onclick={ move |_| { navigator.clone().push(&Route::Home) } }>{"Play"}</button> <button class="text-gray-50 bg-indigo-600 p-2 rounded-md" onclick={ move |_| { navigator.push(&Route::Scores) } }>{"Scores"}</button> <button class="text-gray-50 bg-red-600 p-2 rounded-md">{"Quit"}</button> </div> </nav> } }
补充说明:其实Yew的Callback内部是用Rc封装的,克隆它的性能开销可以忽略不计,官方也推荐这种复用方式。但如果确实不想克隆,上面两种方法都能满足你的需求。
内容的提问来源于stack exchange,提问作者shspencer
相关产品推荐
相关产品推荐

