-
I am trying to build a simple counter app but want to make the buttons a bit prettier with TailwindCSS. //main.rs
use sycamore::prelude::*;
mod button;
mod count;
mod props;
fn main() {
sycamore::render(|cx| {
let state = create_signal(cx, 0i32);
let update = |action| {
if action == 0 {
state.set(0);
} else {
state.set(*state.get() + action);
}
};
view! { cx,
header {
button::Button(updater=&update, action=&-1)
//button::Button(updater=&update, action=&0)
//button::Button(updater=&update, action=&1)
}
count::Count(value=state)
}
});
}
//props.rs
use sycamore::prelude::*;
#[derive(Prop)]
pub struct Base<'a> {
pub value: &'a ReadSignal<i32>,
}
#[derive(Prop)]
pub struct ButtonProps<'a> {
pub updater: &'a dyn Fn(i32),
pub action: &'a i32,
}
//button.rs
use super::props::ButtonProps;
use sycamore::prelude::*;
#[component]
pub fn Button<'a, G: Html>(cx: Scope<'a>, props: ButtonProps<'a>) -> View<G> {
let label = match props.action {
-1 => "-",
0 => "0",
_ => "+",
};
let cls = match props.action {
-1 => "h-12 px-6 m-2 text-lg text-red-100 transition-colors duration-150 bg-red-700 rounded-lg focus:shadow-outline hover:bg-red-800",
0 => "h-12 px-6 m-2 text-lg text-yellow-100 transition-colors duration-150 bg-yellow-700 rounded-lg focus:shadow-outline hover:bg-yellow-800",
_ => "h-12 px-6 m-2 text-lg text-green-100 transition-colors duration-150 bg-green-700 rounded-lg focus:shadow-outline hover:bg-green-800",
};
let on_click = |_| (*props.updater)(*props.action);
view! { cx,
button(on:click=on_click, class=cls) { (label) }
}
}
//count.rs
use super::props::Base;
use sycamore::prelude::*;
#[component]
pub fn Count<'a, G: Html>(cx: Scope<'a>, props: Base<'a>) -> View<G> {
view! { cx,
h1(class="text-3xl") { "Count: " (*props.value.get()) }
}
}
|
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
Try moving in the update function instead of borrowing it. To do so, you'll unfortunately need to add an extra generic to prop struct like so: #[derive(Prop)]
pub struct ButtonProps<'a, F>
where
F: Fn(i32),
{
pub updater: F,
pub action: &'a i32,
} This way you won't have any borrowing issues. However, if you really want to borrow the update function, the problem is that the closure itself lives on the stack which does not last long enough. It needs to be moved onto the heap so that it may live as long as the reactive scope ( let update = create_ref(cx, update) |
Beta Was this translation helpful? Give feedback.
Try moving in the update function instead of borrowing it. To do so, you'll unfortunately need to add an extra generic to prop struct like so:
This way you won't have any borrowing issues.
However, if you really want to borrow the update function, the problem is that the closure itself lives on the stack which does not last long enough. It needs to be moved onto the heap so that it may live as long as the reactive scope (
'a
). The simplest way to do so would be to add the following tomain.rs