6个版本
0.2.3 | 2022年4月14日 |
---|---|
0.2.2 | 2022年4月10日 |
0.1.1 | 2022年3月30日 |
#458 in GUI
32KB
366 行
yewv
将性能和简洁性作为首要任务的Yew快速状态管理模块。
这是为谁准备的?
如果您想在Yew函数组件中使用store,这个库就是为您准备的。
安装
将以下依赖项添加到您的 Cargo.toml
。
[dependencies]
yewv = "0.2"
使用方法
在使用此库时需要遵守以下事项
- 仅适用于Yew函数组件。
- Store和service上下文必须使用
ContextProvider
在父组件或根组件中注册。 - Store和service需要使用在子组件中,使用
use_store
/use_service
。 - 与
map_ref
&watch_ref
不同,map
&watch
是钩子,因此受到某些规则的约束- 应仅在内部调用Yew函数组件。
- 不应在循环、条件或回调内部调用。
带有store的简单应用
// main.rs
use yew::prelude::*;
use yewv::*;
struct AppState {
count: i32,
}
#[function_component(App)]
fn app() -> Html {
let store = StoreContext::new(AppState { count: 0 });
html! {
<ContextProvider<StoreContext<AppState>> context={store}>
<Counter />
<Counter />
</ContextProvider<StoreContext<AppState>>>
}
}
#[function_component(Counter)]
fn counter() -> 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>
}
}
fn main() {
yew::start_app::<App>();
}
带有store和服务的简单应用
// main.rs
use yew::prelude::*;
use yewv::*;
struct AppState {
count: i32,
}
struct AppService {
store: StoreContext<AppState>,
}
impl AppService {
fn increment_count(&self) {
let state = self.store.state();
self.store.set_state(AppState {
count: state.count + 1,
});
}
}
#[function_component(App)]
fn app() -> 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)]
fn counter() -> 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>
}
}
fn main() {
yew::start_app::<App>();
}
map与map_ref
如果您只想引用store拥有的值,应使用map_ref
。与map
不同,map_ref
不获取引用值的所有权。通常在可能的情况下,使用map_ref
比使用map
更好。然而,并非总是可以使用map_ref
。例如,如果您想访问的值不是存储状态拥有的,则需要使用map
let length = store.map(|state| state.some_vector.len());
为什么这么快?
自定义钩子
存储使用高度优化的自定义钩子,以提高性能和内存效率。
仅在需要时渲染
使用map
、map_ref
、watch
和watch_ref
对存储进行的订阅,只有在观察到的值已更改时才会触发组件的渲染。
引用 VS 所有权
不是通过组件传播应用程序状态的克隆/复制,而是使用引用。
良好实践
仅引用所需的
在观察存储中的值时,请确保您没有获取超过必要的部分。例如,如果您只对向量中的一个值感兴趣,就没有必要引用整个向量。
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"));
大型应用程序中存储的隔离
当且仅当合理时,尝试将您的单体存储拆分为多个。这样做将提高整个应用程序的性能。
版权信息
- Rust - MIT 或 Apache-2.0
- Yew - MIT 或 Apache-2.0
依赖关系
~12MB
~218K SLoC