Leptos - template not reactive with struct

53 Views Asked by At

In the code below, there are two instances where the task.title is being displayed, one using task_title (a memoized value) and the other directly from task.get().title. However, only the memorized value (task_title) updates when the input field's value changes.

Leptos doc seems to recommend use the RwSignal for the field inside the struct, is there any alternative to this problem?

The Task struct in the example come from an external crate, I want to avoid duplicating that to use internal Signal.

use leptos::*;
use leptos_meta::*;
use leptos_router::*;

#[component]
pub fn App() -> impl IntoView {
    provide_meta_context();

    view! {
        <Stylesheet id="leptos" href="/pkg/web-api.css"/>
        <Router>
            <Routes>
                <Route path="/" view=HomePage/>
                <Route path="/test" view=Test/>
            </Routes>
        </Router>
    }
}

#[derive(Debug, Clone)]
struct Task {
    id: Option<i64>,
    title: String,
    description: Option<String>,
}

#[component]
fn HomePage() -> impl IntoView {
    let (task, set_task) = create_signal(Task {
        id: None,
        title: "teste".to_string(),
        description: Some("".to_string()),
    });

    let task_title = create_memo(move |_| task.get().title.clone());
    view! {
        <div>
            <h1>HomePage</h1>
            {task_title} <<<<< update when changed
            <hr/>
            {task.get().title} <<<<< doenst change when updated
            <hr/>
            <div>
                <input
                    type="text"
                    prop:value=task.get().title
                    on:input=move |e| {
                        let new_title = event_target_value(&e);
                        set_task
                            .set(Task {
                                id: task.get().id,
                                title: new_title,
                                description: task.get().description.clone(),
                            });
                    }
                />

            </div>
        </div>
    }
}
0

There are 0 best solutions below