DioxusLabs / dioxus

Fullstack GUI library for web, desktop, mobile, and more.
https://dioxuslabs.com
Apache License 2.0
19.35k stars 740 forks source link

Resource does not restart from async event handler #2440

Open luveti opened 1 month ago

luveti commented 1 month ago
use dioxus::prelude::*;

pub fn main() {
    launch(app)
}

pub fn app() -> Element {
    let mut num = use_server_future(get_next_number);

    rsx! {
        div {
            // This does work
            // onclick: move |e| {
            //     if let Some(num) = &mut num {
            //         num.restart();
            //     }
            // },
            // This does not work
            onclick: move |e| async move {
                if let Some(num) = &mut num {
                    num.restart();
                }
            },
            if let Some(num) = num {
                match num.value().as_ref() {
                    Some(num) => match num.as_ref() {
                        Ok(num) => rsx! { p { "Next number is {num}" } },
                        Err(e) => rsx! { p { "Loading next number failed, {e}" } },
                    },
                    None =>  rsx! { p { "Loading..." } }
                }
            }
        }
    }
}

#[server]
async fn get_next_number() -> Result<u32, ServerFnError> {
    static mut NUM: u32 = 0;
    unsafe {
        NUM += 1;
        Ok(NUM)
    }
}

Environment:

Questionnaire

luveti commented 1 month ago

Poking around a bit, it looks like using the following works:

pub fn app() -> Element {
    let mut num = use_server_future(get_next_number);

    rsx! {
        div {
            onclick: move |e| async move {
                queue_effect(move || {
                    if let Some(num) = &mut num {
                        num.restart();
                    }
                });
            },
            if let Some(num) = num {
                match num.value().as_ref() {
                    Some(num) => match num.as_ref() {
                        Ok(num) => rsx! { p { "Next number is {num}" } },
                        Err(e) => rsx! { p { "Loading next number failed, {e}" } },
                    },
                    None =>  rsx! { p { "Loading..." } }
                }
            }
        }
    }
}

Is this the recommended work around? If so, this may be a nice addition to the Event Handlers page.