In Yew, I am attempting to bind a callback to the window resize event, triggering a Msg::Resize
update. I have encountered: E0631 Type mismatch in closure arguments.`
Expanded version of the code can be found here:
This is the minimalist test case:
use gloo_console::log;
use gloo_events::EventListener;
use yew::prelude::*;
pub struct CanvasQuestion {}
pub enum Msg { Resize }
impl Component for CanvasQuestion {
type Message = Msg;
type Properties = ();
fn create(_ctx: &Context<Self>) -> Self {
Self { }
}
fn view(&self, _ctx: &Context<Self>) -> Html {
html! { <canvas id="canvas"/> }
}
fn rendered(&mut self, ctx: &Context<Self>, first_render: bool) {
if first_render {
// WORKS
ctx.link().send_message(Msg::Resize);
// found signature of `fn(yew::Event)
// let on_window_resize = |_event: Event| { // BROKEN
let on_window_resize = |_event: &Event| { // WORKS
ctx.link().send_message(Msg::Resize);
};
// expected signature of `for<'r> fn(&'r yew::Event)
EventListener::new( &web_sys::window().unwrap(),
"resize", on_window_resize );
}
}
fn update(&mut self, _ctx: &Context<Self>, msg: Self::Message) -> bool {
match msg {
Msg::Resize => { true } // rerender
}
}
}
Update
Replacing on_window_resize = |_event: Event|
with on_window_resize = |_event: &Event|
fixes the below errors
error[E0631]: type mismatch in closure arguments
--> src/components/canvas_question.rs:68:43
|
64 | let on_window_resize = |_event: Event| {
| --------------- found signature of `fn(yew::Event) -> _`
...
67 | EventListener::new( &web_sys::window().unwrap(),
| ------------------ required by a bound introduced by this call
68 | "resize", on_window_resize );
| ^^^^^^^^^^^^^^^^ expected signature of `for<'r> fn(&'r yew::Event) -> _`
|
note: required by a bound in `EventListener::new`
--> /home/jamie/.cargo/registry/src/github.com-1ecc6299db9ec823/gloo-events-0.1.2/src/lib.rs:338:12
|
338 | F: FnMut(&Event) + 'static,
| ^^^^^^^^^^^^^ required by this bound in `EventListener::new`
But exposes rust lifetime issues trying to access ctx.link()
from inside the closure.
error[E0521]: borrowed data escapes outside of associated function
--> src/components/fractal.rs:70:28
|
51 | fn rendered(&mut self, ctx: &Context<Self>, first_render: bool) {
| --- - let's call the lifetime of this reference `'1`
| |
| `ctx` is a reference that is only valid in the associated function body
...
70 | let listener = EventListener::new( &web_sys::window().unwrap(),
| ____________________________^
71 | | "resize", on_window_resize );
| | ^
| | |
| |___________________________________________________________________________`ctx` escapes the associated function body here
| argument requires that `'1` must outlive `'static`
- Is there a way of defining a 'static lifetime for
ctx: Context
? - Is
ctx.link()
the best way to trigger internal message passing? - Would it be easier to call
self.update(Msg::Resize)
directly instead? - Does
ctx.link()
need to be stored asself.link
in the CanvasQuestion struct? - What is the correct way to write and bind the
on_window_resize()
function?