use crate::{transport::SerializeContextEntry, Transportable}; use dioxus_core::use_hook; /// This allows you to send data from the server to the client *during hydration*. /// - When compiled as server, the closure is ran and the resulting data is serialized on the server and sent to the client. /// - 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. /// - When otherwise compiled, the closure is run directly with no serialization. /// /// The order this function is run on the client needs to be the same order initially run on the server. /// /// If Dioxus fullstack cannot find the data on the client, it will run the closure again to get the data. /// /// # Example /// ```rust /// use dioxus::prelude::*; /// /// fn app() -> Element { /// let state1 = use_server_cached(|| { /// 1234 /// }); /// /// unimplemented!() /// } /// ``` #[track_caller] pub fn use_server_cached(server_fn: impl Fn() -> O) -> O where O: Transportable + Clone, M: 'static, { let location = std::panic::Location::caller(); use_hook(|| server_cached(server_fn, location)) } pub(crate) fn server_cached( value: impl FnOnce() -> O, #[allow(unused)] location: &'static std::panic::Location<'static>, ) -> O where O: Transportable + Clone, M: 'static, { let serialize = crate::transport::serialize_context(); #[allow(unused)] let entry: SerializeContextEntry = serialize.create_entry(); #[cfg(feature = "server")] { let data = value(); entry.insert(&data, location); data } #[cfg(all(not(feature = "server"), feature = "web"))] { match entry.get() { Ok(value) => value, Err(_) => value(), } } #[cfg(not(any(feature = "server", feature = "web")))] { value() } }