- Notifications
You must be signed in to change notification settings - Fork0
A lightning fast state management module for Yew.
License
yewv/yewv
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
A lightning fast state management module for Yew built with performance and simplicity as a first priority.
If you wish to use a store alongside Yew fonction components, this library is made for you.
Add the following dependency to yourCargo.toml
.
[dependencies]yewv ="0.2"
The following need to be respected while using this library:
- Only works with Yew function components.
- Store and service contexts must be registered in aparent orroot component with
ContextProvider
. - Store and service need to be used in achild component with
use_store
/use_service
. - As opposed to
map_ref|watch_ref
,map|watch
are hooks and shouldnot be called inside loops, conditions or callbacks.
// main.rsuse yew::prelude::*;use yewv::*;structAppState{count:i32,}#[function_component(App)]fnapp() ->Html{let store =StoreContext::new(AppState{count:0});html!{ <ContextProvider<StoreContext<AppState>> context={store}> <Counter /> <Counter /> </ContextProvider<StoreContext<AppState>>>}}#[function_component(Counter)]fncounter() ->Html{let store =use_store::<AppState>();let count = store.map_ref(|state|&state.count);let onclick ={let store = store.clone();move |_|{let state = store.state(); store.set_state(AppState{count: state.count +1,});}};html!{ <button{onclick}>{format!("{} +", count)}</button>}}fnmain(){ yew::start_app::<App>();}
// main.rsuse yew::prelude::*;use yewv::*;structAppState{count:i32,}structAppService{store:StoreContext<AppState>,}implAppService{fnincrement_count(&self){let state =self.store.state();self.store.set_state(AppState{count: state.count +1,});}}#[function_component(App)]fnapp() ->Html{let store =StoreContext::new(AppState{count:0});let service =ServiceContext::new(AppService{store: store.clone(),});html!{ <ContextProvider<StoreContext<AppState>> context={store}> <ContextProvider<ServiceContext<AppService>> context={service}> <Counter /> <Counter /> </ContextProvider<ServiceContext<AppService>>> </ContextProvider<StoreContext<AppState>>>}}#[function_component(Counter)]fncounter() ->Html{let service =use_service::<AppService>();let store =use_store::<AppState>();let count = store.map_ref(|state|&state.count);let onclick =move |_| service.increment_count();html!{ <button{onclick}>{format!("{} +", count)}</button>}}fnmain(){ yew::start_app::<App>();}
If you only wish to reference a value owned by the store, you should usemap_ref
orwatch_ref
.As opposed tomap|watch
,map_ref|watch_ref
don't take ownership of the referenced value.It is usually preferable to usemap_ref|watch_ref
overmap|watch
when possible.However, it is not always possible to usemap_ref|watch_ref
. For instance, if the value you wish to access is not owned by the store state, you will need to usemap|watch
:
let length = store.map(|state| state.some_vector.len());
The store utilizes highly optimized custom hooks for better performance and memory efficiency.
Subscriptions done to the store withmap
,map_ref
,watch
andwatch_ref
will only trigger a re-render if the observed value has changed.
Instead of propagating clone/copy of the application state throughout components, references are used.
When you are observing a value in a store, make sure you are not taking more than necessary. For instance, if you are only interested in a single value from a vector, there is no need to reference the entire vector:
let first = store.map_ref(|state|&state.some_vector[0]);let last = store.map_ref(|state| state.some_vector.iter().last().expect("to have a value"));
When and where it makes sense, try to break your monolithic stores into multiple. Doing so will improve the performance of the application as a whole.
- Rust -MIT orApache-2.0
- Yew -MIT orApache-2.0
About
A lightning fast state management module for Yew.