dioxus
dioxus copied to clipboard
sync server functions in a use future fail to hydrate
Problem
Running this program fails to hydrate:
#![allow(non_snake_case, unused)]
use dioxus::prelude::*;
use dioxus_fullstack::{
launch::{self, LaunchBuilder},
prelude::*,
};
fn app(cx: Scope) -> Element {
let future = use_future(cx, (), |_| async move {
let data = get_server_data().await.unwrap();
println!("Client received: {}", data);
});
match future.value() {
Some(_) => render! { div {} },
None => render! {"Loading..."},
}
}
#[server]
async fn get_server_data() -> Result<String, ServerFnError> {
Ok("Hello from the server!".to_string())
}
fn main() {
LaunchBuilder::new(app).launch()
}
Screenshots
Environment:
- Dioxus version:
master - Rust version:
nightly - OS info: MacOS
- App platform:
fullstack
Questionnaire
- [ ] I'm interested in fixing this myself but don't know where to start
- [x] I would like to fix and I have a solution
- [ ] I don't have time to fix this right now, but maybe later
This is caused by https://github.com/DioxusLabs/dioxus/pull/1710:
- If a user tries to use a use_future with a sync server function, on the server it will poll once and resolve to a value. On the client, it will not resolve immediately. This can cause hydration to fail, because the server can renderer something different than the client.
In reality, users should probably be using use_server_future instead of use_future. We could:
- Warn the user about the issue and force them to change it to a use_server_future
- Always wait at least one poll before resolving server functions
Encountering similar problem on the use_server_future as well in the issue here: https://github.com/DioxusLabs/dioxus/issues/1950
Closed by #2005