1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
//! Location agnostic shared state for yew components. //! ## Usage //! //! Give your component `GlobalHandle` properties and wrap it with `SharedStateComponent`. //! This may be done for any `T` that implements `Clone` + `Default`. //! ```rust //! struct Model { //! handle: GlobalHandle<T>, //! } //! //! impl Component for Model { //! type Properties = GlobalHandle<T>; //! ... //! } //! //! type MyComponent = SharedStateComponent<Model>; //! ``` //! //! Access current state with `state`. //! ```rust //! let state: &T = self.handle.state(); //! ``` //! //! Modify shared state from anywhere using `reduce` //! ```rust //! // GlobalHandle<MyAppState> //! self.handle.reduce(|state| state.user = new_user); //! ``` //! //! or from a callback with `reduce_callback`. //! ```rust //! // GlobalHandle<usize> //! let onclick = self.handle.reduce_callback(|state| *state += 1); //! html! { //! <button onclick = onclick>{"+1"}</button> //! } //! ``` //! //! `reduce_callback_with` provides the fired event. //! ```rust //! let oninput = self //! .handle //! .reduce_callback_with(|state, i: InputData| state.user.name = i.value); //! //! html! { //! <input type="text" placeholder = "Enter your name" oninput = oninput /> //! } //! ``` //! //! ### Properties with Shared State //! //! Get shared state in custom props with `SharedState`. //! ```rust //! #[derive(Clone, Properties)] //! pub struct Props { //! #[prop_or_default] //! pub handle: GlobalHandle<AppState>, //! } //! //! impl SharedState for Props { //! type Handle = GlobalHandle<AppState>; //! //! fn handle(&mut self) -> &mut Self::Handle { //! &mut self.handle //! } //! } //! ``` //! //! ### State Persistence //! //! Persistent storage requires that `T` also implement `Serialize`, //! `Deserialize`, and `Storable`. //! ```rust //! use serde::{Serialize, Deserialize}; //! use yew_state::Storable; //! use yew::services::storage::Area; //! //! #[derive(Serialize, Deserialize)] //! struct T; //! //! impl Storable for T { //! fn key() -> &'static str { //! "myapp.storage.t" //! } //! //! fn area() -> Area { //! // or Area::Session //! Area::Local //! } //! } //! ``` //! //! Then use `StorageHandle` instead of `GlobalHandle`. mod component; mod handle; mod handler; pub use yew::services::storage::Area; pub use component::SharedStateComponent; pub use handle::{GlobalHandle, Handle, SharedState, StorageHandle}; pub use handler::Storable;