一键导入
reactivity-and-stores
Use when building state management and reactivity in pocopine — understand the reactive model, App stores, and provide/inject context
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Use when building state management and reactivity in pocopine — understand the reactive model, App stores, and provide/inject context
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Use when turning a Claude Design (or any mockup/design) into a well-structured pocopine app — choosing app architecture (a store plus layout/leaf components), translating inline styles into Pine Stylekit, wiring icons and resizable regions, and verifying the result.
Use when working with the pocopine Pine icons feature — the `icon!` proc macro for compile-time Rust SVG embedding, or the `<pine-icon>` template primitive with `register_icons!` for tree-shaking-friendly template rendering.
Use when building styles with Pine Stylekit, the Pocopine-native utility-CSS compiler, or working with @theme tokens and CSS generation in Rust/WASM projects
Use when building enter/leave transitions, layout animations, stagger effects, or spring-physics motion in pocopine components
Use when implementing authentication in pocopine apps — JWT verification, credentials, OAuth providers, session management, or guards
Use when defining background jobs, enqueueing work, configuring workers, or troubleshooting job execution in pocopine apps
| name | reactivity-and-stores |
| description | Use when building state management and reactivity in pocopine — understand the reactive model, App stores, and provide/inject context |
Pocopine's reactivity system automatically updates templates and effects whenever component state changes. Stores are singleton components for global state shared across your app. Provide/inject enables parent components to pass context down to descendants through the scope chain.
#[component] struct fields, #[store] singletons)get/set traps and dependency tracking)$store.<name> in templates, pocopine::store::<T>() in Rust)provide(), child inject())dispatch! macro or Handle::update)effect(f: impl Fn() + 'static) — Run closure; subscribe to any (ScopeId, key) accessed during execution. Reruns when subscribed fields change.signal(v: T) -> (Signal<T>, Setter<T>) — Create a typed reactive cell; split read/write pair.rw_signal(v: T) -> RwSignal<T> — Combined read+write handle for a reactive cell.Computed<T> — A derived value that auto-memoizes and updates when its source signals change.track(scope_id, key) / trigger(scope_id, key) — Low-level: manually subscribe/notify inside an effect.DEPS, REVERSE, SIGNAL_DEPS, SIGNAL_REVERSE, QUEUE, CLEANUPS drive the effect engine.#[store] struct T — Macro that emits a singleton #[component]. Accessible via $store.<kebab-case> in templates and pocopine::store::<T>() in Rust.Store trait — Implemented by #[store] macros; requires sibling #[handlers] impl (empty is fine).Handle<T> — Typed reference to a component or store scope. Use handle.update(|s| { ... }) to mutate and trigger reactivity.pocopine::store::<T>() — Short-hand for T::__handle(). Returns a Handle<T> to the singleton.handle.update(f) / handle.with(f) — Mutate (reactive) or read (non-reactive) the underlying state.ContextKey<T> — Opaque, unique, typed context key. Created via create_context! macro or ContextKey::new("debug-name").provide(key: &ContextKey<T>, value: T) — Store value under key on the current scope; descendants can inject it.inject(key: &ContextKey<T>) -> Option<T> — Walk up scope-parent chain; return first matching key's value (must be T: Clone).context::set_parent(child, parent). Teleported / slotted content preserves authoring parent.pp-bind: reactive).$dispatch events captured with pp-on:event.dispatch!(server_fn(args).await, |s, result| { ... }); expands to spawn_local + Handle::update.From /home/zempare-mambisi/RustProjects/pocopine/examples/todo/src/lib.rs:
#[derive(Serialize, Deserialize)]
#[store]
pub struct Preferences {
pub theme: String,
}
impl Default for Preferences {
fn default() -> Self {
Self { theme: "light".into() }
}
}
#[handlers]
impl Preferences {}
#[wasm_bindgen(start)]
fn main() {
App::new()
.register::<TodoList>()
.store::<Preferences>()
.run();
}
Template access: <span pp-text="$store.preferences.theme"></span>
Rust access: pocopine::store::<Preferences>().update(|p| p.theme = "dark".into())
From /home/zempare-mambisi/RustProjects/pocopine/examples/blog/src/lib.rs:
#[pocopine::server]
pub async fn get_post(post_id: u32) -> ServerResult<Post> {
match post_id {
1 => Ok(Post { id: 1, title: "Hello".into(), body: "...".into() }),
_ => Err(ServerError::App(format!("no post {post_id}")))
}
}
#[derive(Default, Serialize, Deserialize)]
#[component]
pub struct BlogPost {
#[prop]
pub post_id: u32,
pub title: String,
pub loading: bool,
}
#[handlers]
impl BlogPost {
pub fn on_mount(&mut self) {
self.loading = true;
let post_id = self.post_id;
dispatch!(get_post(post_id).await, |s, result| {
s.loading = false;
match result {
Ok(p) => s.title = p.title,
Err(e) => { /* handle error */ }
}
});
}
}
From RFC-027 pattern (root provides itself to children):
#[handlers]
impl DropdownMenuRoot {
pub fn on_mount(&mut self) {
pocopine::provide("dropdown-menu", pocopine::this::<Self>());
}
}
#[handlers]
impl DropdownMenuItem {
pub fn on_click(&mut self) {
if let Some(menu) = pocopine::inject::<Handle<DropdownMenuRoot>>("dropdown-menu") {
menu.update(|m| m.close());
}
}
}
Scope::invoke calls trigger_scope(id) after any handler, not per-field. Use dispatch! for granular updates from async.get serializes through serde_wasm_bindgen::to_value. Hot reads should use Signal<T> or handle with() instead.#[handlers] — Even an empty impl block is mandatory alongside #[store].provide(key, v1) then provide(key, v2) from the same scope replaces v1 inline (no stack).on_ready / post-walk hooks if inject must wait.Handle::update drops the entire field cache; next template proxy reads fetch fresh state from Rust.crates/pocopine-core/src/ — reactive.rs, signal.rs, store.rs, context.rs, handle.rs, scope.rsdocs/reactivity/01-current-design.md — The five thread-locals, effect lifecycle, dependency trackingdocs/reactivity/03-signals.md — Signal types, computed, watch, on_cleanup, batch API (design sketch)docs/components/02-state.md — Four state patterns (local, parent→child, child→parent, stores), async data with dispatch!