组件生命周期
使用 use_hook
初始化状态
use_hook
允许您为组件创建新状态。传递给 use_hook
的闭包将在组件首次渲染时被调用。每次组件重新渲染时,都会复用初始运行时创建的值。
rust
fn UseHook() -> Element {
// The closure that is passed to use_hook will be called once the first time the component is rendered
let random_number = use_hook(|| {
let new_random_number = random_number();
log!("{new_random_number}");
new_random_number
});
rsx! {
div { "Random {random_number}" }
}
}
重新渲染
当某个值发生变化时,您可以使用追踪值来重新渲染组件。
rust
fn Rerenders() -> Element {
let mut count = use_signal(|| 0);
log!("Rerendering parent component with {}", *count.peek());
rsx! {
button { onclick: move |_| count += 1, "Increment" }
// Since we read count here, the component will rerender when count changes
Count { current_count: count() }
}
}
// If the count prop changes, the component will rerender
#[component]
fn Count(current_count: i32) -> Element {
log!("Rerendering child component with {current_count}");
rsx! {
div { "The count is {current_count}" }
}
}
⚠️ 请勿在组件主体中修改状态
应避免在组件主体中更改状态。若在组件主体中读写状态,可能导致无限循环------组件因状态变更触发重新渲染,进而引发新一轮状态变更。
rust
fn Bad() -> Element {
let mut count = use_signal(|| 0);
// ❌ 不要在组件主体中修改状态。这很容易导致无限循环!
count += 1;
rsx! { "{count}" }
}
相反,应使用 use_memo
、use_resource
或在 effect
中修改状态来推导状态。
使用 Effect
你可以使用effect
在组件每次渲染时执行代码。
rust
fn Effect() -> Element {
// Effects 在组件渲染后执行
// 可用于读取或修改渲染后的组件component
use_effect(|| {
log!("Effect ran");
document::eval(&format!(
"document.getElementById('effect-output').innerText = 'Effect ran'"
));
});
rsx! {
div { id: "effect-output", "This will be changed by the effect" }
}
}
使用 Drop
清理组件
组件被 drop
前,会释放其所有挂钩。可利用此 drop
行为清理组件使用的资源。若仅需 drop
效果,可使用 use_drop
挂钩。
rust
fn TogglesChild() -> Element {
let mut show = use_signal(|| true);
rsx! {
button { onclick: move |_| show.toggle(), "Toggle" }
if show() {
Child {}
}
}
}
fn Child() -> Element {
// 你可以使用 use_drop 钩子来清理任何资源
use_drop(|| {
log!("Child dropped");
});
rsx! {
div { "Child" }
}
}