You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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类型专门用于组件间传递回调,它比原始函数指针更灵活,支持闭包捕获环境,还能避免生命周期问题。修改步骤如下:

  1. 将Props中的函数类型改为Callback<Event>
  2. 传递函数时用Callback::from包裹
  3. 子组件中通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 03:40:39