dioxus_fullstack_core/
server_cached.rs

1use crate::{transport::SerializeContextEntry, Transportable};
2use dioxus_core::use_hook;
3
4/// This allows you to send data from the server to the client *during hydration*.
5/// - When compiled as server, the closure is ran and the resulting data is serialized on the server and sent to the client.
6/// - When compiled as web client, the data is deserialized from the server if already available, otherwise runs on the client. Data is usually only available if this hook exists in a component during hydration.
7/// - When otherwise compiled, the closure is run directly with no serialization.
8///
9/// The order this function is run on the client needs to be the same order initially run on the server.
10///
11/// If Dioxus fullstack cannot find the data on the client, it will run the closure again to get the data.
12///
13/// # Example
14/// ```rust
15/// use dioxus::prelude::*;
16///
17/// fn app() -> Element {
18///    let state1 = use_server_cached(|| {
19///       1234
20///    });
21///
22///    unimplemented!()
23/// }
24/// ```
25#[track_caller]
26pub fn use_server_cached<O, M>(server_fn: impl Fn() -> O) -> O
27where
28    O: Transportable<M> + Clone,
29    M: 'static,
30{
31    let location = std::panic::Location::caller();
32    use_hook(|| server_cached(server_fn, location))
33}
34
35pub(crate) fn server_cached<O, M>(
36    value: impl FnOnce() -> O,
37    #[allow(unused)] location: &'static std::panic::Location<'static>,
38) -> O
39where
40    O: Transportable<M> + Clone,
41    M: 'static,
42{
43    let serialize = crate::transport::serialize_context();
44
45    #[allow(unused)]
46    let entry: SerializeContextEntry<O> = serialize.create_entry();
47
48    #[cfg(feature = "server")]
49    {
50        let data = value();
51        entry.insert(&data, location);
52        data
53    }
54
55    #[cfg(all(not(feature = "server"), feature = "web"))]
56    {
57        match entry.get() {
58            Ok(value) => value,
59            Err(_) => value(),
60        }
61    }
62
63    #[cfg(not(any(feature = "server", feature = "web")))]
64    {
65        value()
66    }
67}