如何在Yew中传递函数作为Prop?解决编译报错问题
问题:在Yew中通过Props传递函数给子组件编译报错
我希望通过Props将一个函数传递给子组件供其使用,但当前代码编译失败,移除do_this仅传递val时编译正常。
原代码
use log::info; use yew::html::onclick::Event; use yew::prelude::*; // 定义包含目标函数的Props #[derive(yew::Properties, PartialEq)] pub struct MyProps { pub do_this: fn(Event) -> (), pub val: String, } #[function_component(Base)] pub fn home(props: &MyProps) -> Html { let do_this_func = props.do_this.clone(); html! { <button onclick={move |e: Event| do_this_func(e)}> {"press me"} </button> } } // 传递函数给子组件 #[function_component(App)] pub fn app() -> Html { fn do_this_func(s: Event) { info!("clicked from my func") } html! { <Base do_this={do_this_func} val={"hello".to_string()} /> } } fn main() { wasm_logger::init(wasm_logger::Config::default()); yew::start_app::<App>(); }
编译错误信息
Compiling yew-app v0.1.0 (/Users/sasacocic/development/tinkering/yew-app) error[E0277]: the trait bound `fn(MouseEvent) {do_this_func}: IntoPropValue<fn(MouseEvent)>` is not satisfied --> src/main.rs:25:24 | 25 | <Base do_this={do_this_func} val={"hello".to_string()} /> | ------- ^^^^^^^^^^^^ the trait `IntoPropValue<fn(MouseEvent)>` is not implemented for `fn(MouseEvent) {do_this_func}` | | | required by a bound introduced by this call | = help: the following other types implement trait `IntoPropValue<T>`: <&'static str as IntoPropValue<AttrValue>> <&'static str as IntoPropValue<Classes>> <&'static str as IntoPropValue<Option<AttrValue>>> <&'static str as IntoPropValue<Option<String>>> <&'static str as IntoPropValue<String>> <&T as IntoPropValue<Option<T>>> <&T as IntoPropValue<T>> <Classes as IntoPropValue<AttrValue>> and 6 others note: required by a bound in `MyPropsBuilder::<MyPropsBuilderStep_missing_required_prop_do_this>::do_this` --> src/main.rs:5:10 | 5 | #[derive(yew::Properties, PartialEq)] | ^^^^^^^^^^^^^^^ required by this bound in `MyPropsBuilder::<MyPropsBuilderStep_missing_required_prop_do_this>::do_this` 6 | pub struct MyProps { 7 | pub do_this: fn(Event) -> (), | ------- required by a bound in this = note: this error originates in the derive macro `yew::Properties` (in Nightly builds, run with -Z macro-backtrace for more info)
解决方案
方案1:使用Yew推荐的Callback类型(优先选择)
Yew提供了Callback类型专门用于组件间传递回调,它比原始函数指针更灵活,支持闭包捕获环境,还能避免生命周期问题。修改步骤如下:
- 将Props中的函数类型改为
Callback<Event> - 传递函数时用
Callback::from包裹 - 子组件中通过
emit方法调用回调
修改后的代码:
use log::info; use yew::html::onclick::Event; use yew::prelude::*; #[derive(yew::Properties, PartialEq)] pub struct MyProps { pub do_this: Callback<Event>, pub val: String, } #[function_component(Base)] pub fn home(props: &MyProps) -> Html { html! { <button onclick={props.do_this.clone()}> {"press me"} </button> } } #[function_component(App)] pub fn app() -> Html { let do_this_func = Callback::from(|_s: Event| { info!("clicked from my func") }); html! { <Base do_this={do_this_func} val={"hello".to_string()} /> } } fn main() { wasm_logger::init(wasm_logger::Config::default()); yew::start_app::<App>(); }
方案2:显式转换为函数指针
如果坚持使用原始函数指针,只需在传递时将具体函数强制转换为函数指针类型即可:
// 在App组件的html宏中修改 <Base do_this={do_this_func as fn(Event)} val={"hello".to_string()} />
说明
方案1是Yew官方推荐的回调传递方式,Callback是为组件间通信设计的类型,能更好地和Yew的响应式系统配合,建议优先使用。
内容的提问来源于stack exchange,提问作者sasac
相关产品推荐
相关产品推荐

