Reactive Route Params
Dioxus component props derived from route parameters (like :contact_id) are plain String values — they don’t trigger reactivity on their own. If you pass a route param directly into a use_resource closure, the resource captures the initial value at mount time and never re-fetches when the user navigates to a different route of the same component.
The Problem
Section titled “The Problem”When MessagingContactView receives a new contact_id from the router, hooks that captured the old value in their closure don’t re-run:
#[component]pub fn MessagingContactView(contact_id: String) -> Element { // ❌ Bug: captures contact_id once at mount time. // Navigating /messaging/abc → /messaging/xyz won't re-fetch. let contact_resource = use_resource({ let id = contact_id.clone(); move || { let id = id.clone(); async move { get_contact_api(id).await } } }); // ...}The component re-renders with the new prop, but use_resource already has its closure bound to the original contact_id.
The Fix
Section titled “The Fix”Wrap the prop in use_memo(use_reactive!(...)) to create a reactive signal that use_resource automatically tracks:
#[component]pub fn MessagingContactView(contact_id: String) -> Element { // ✅ Converts a plain String prop into a reactive memo. // use_reactive! captures contact_id by value and re-emits on change. // use_memo deduplicates — only triggers downstream when the value actually differs. let id_memo = use_memo(use_reactive!(|contact_id| contact_id.clone()));
let contact_resource = use_resource(move || { let id = id_memo(); async move { get_contact_api(id).await } });
let calls_resource = use_resource(move || { let id = id_memo(); async move { get_contact_calls_api(id).await } });
let messages_resource = use_resource(move || { let id = id_memo(); async move { let uuid = uuid::Uuid::parse_str(&id) .map_err(|e| ServerFnError::new(e.to_string()))?; get_contact_messages_api(uuid).await } });
let contact_uuid = uuid::Uuid::parse_str(&id_memo.read()).ok(); // ...}How It Works
Section titled “How It Works”-
use_reactive!(|contact_id| contact_id.clone())— creates a closure that Dioxus calls whenever the component’scontact_idprop changes. It captures the prop by name and re-emits the new value. -
use_memo(...)— wraps the reactive closure in a memoized signal. The memo only notifies subscribers when the value actually changes (deduplication). -
use_resource(move || { let id = id_memo(); ... })— readingid_memo()inside the resource closure subscribes to it. Whenid_memoupdates, all three resources automatically re-run their async fetchers.
When to Use This Pattern
Section titled “When to Use This Pattern”Apply use_memo(use_reactive!(...)) whenever a component:
- Receives a route parameter as a
String(or other non-signal) prop - Uses that prop inside
use_resource,use_effect, or other reactive hooks - Stays mounted while the route param changes (same component, different param)
Key Files
Section titled “Key Files”| File | Role |
|---|---|
src/mods/messaging/views/messaging_contact_view.rs | Applies the pattern for contact, calls, and messages resources |