fix(hooks): 修复 wasm32 target 编译失败
之前验证只跑了 server target(cargo build --all-features),漏掉 wasm32 前端 target,导致三类错误未被捕获: 1. event_listener.rs wasm 分支缺 use dioxus::prelude::*: use_hook/use_effect/use_drop 来自 prelude,之前重写时误删。补回。 2. event_listener.rs use_effect 闭包 move 冲突(E0507/E0310): use_effect 回调是 FnMut,但 acquire 是 FnOnce、handler 要 move 进事件 闭包。用 Option::take 模式包裹,首次运行消费,避免重复 move。同时给 A 加上 'static 约束。 3. query.rs items/total/footer.rs sync_visible 缺 mut: wasm 分支的 .set() 调用需要 mut 绑定。之前为消 server target 的 unused_mut 警告误删,改用 cfg_attr 在非 wasm 时压制警告。 教训:fullstack 项目必须同时验证 wasm32 与 server 两个 target,单一 target 通过不代表整体可用。
This commit is contained in:
parent
291189fb77
commit
2b6b2ca9e4
@ -21,7 +21,7 @@ pub fn Footer() -> Element {
|
|||||||
|
|
||||||
// 根据 window 当前滚动位置同步 visible(注册监听后立即调用一次,避免首屏漏判)。
|
// 根据 window 当前滚动位置同步 visible(注册监听后立即调用一次,避免首屏漏判)。
|
||||||
// 滚动事件回调里也复用同一份判断逻辑。
|
// 滚动事件回调里也复用同一份判断逻辑。
|
||||||
let sync_visible = move || {
|
let mut sync_visible = move || {
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
{
|
{
|
||||||
if let Some(w) = web_sys::window() {
|
if let Some(w) = web_sys::window() {
|
||||||
|
|||||||
@ -30,12 +30,13 @@
|
|||||||
/// );
|
/// );
|
||||||
/// ```
|
/// ```
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
pub fn use_event_listener<T, A, F>(acquire: A, event: &'static str, mut handler: F)
|
pub fn use_event_listener<T, A, F>(acquire: A, event: &'static str, handler: F)
|
||||||
where
|
where
|
||||||
T: AsRef<web_sys::EventTarget> + Clone + 'static,
|
T: AsRef<web_sys::EventTarget> + Clone + 'static,
|
||||||
A: FnOnce() -> Option<T>,
|
A: FnOnce() -> Option<T> + 'static,
|
||||||
F: FnMut() + 'static,
|
F: FnMut() + 'static,
|
||||||
{
|
{
|
||||||
|
use dioxus::prelude::*;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
@ -45,7 +46,14 @@ where
|
|||||||
use_hook(|| Rc::new(RefCell::new(None)));
|
use_hook(|| Rc::new(RefCell::new(None)));
|
||||||
let state_for_drop = state.clone();
|
let state_for_drop = state.clone();
|
||||||
|
|
||||||
|
// use_effect 的回调是 FnMut(可能多次运行),但 acquire 是 FnOnce、handler 要
|
||||||
|
// move 进事件闭包。用 Option 包裹后 take(),首次运行消费掉,避免重复 move。
|
||||||
|
let mut acquire = Some(acquire);
|
||||||
|
let mut handler = Some(handler);
|
||||||
|
|
||||||
use_effect(move || {
|
use_effect(move || {
|
||||||
|
let Some(acquire) = acquire.take() else { return };
|
||||||
|
let Some(mut handler) = handler.take() else { return };
|
||||||
let Some(target) = acquire() else { return };
|
let Some(target) = acquire() else { return };
|
||||||
let target_clone = target.clone();
|
let target_clone = target.clone();
|
||||||
let closure = wasm_bindgen::prelude::Closure::wrap(Box::new(move || {
|
let closure = wasm_bindgen::prelude::Closure::wrap(Box::new(move || {
|
||||||
@ -77,7 +85,7 @@ where
|
|||||||
pub fn use_event_listener<T, A, F>(acquire: A, event: &'static str, handler: F)
|
pub fn use_event_listener<T, A, F>(acquire: A, event: &'static str, handler: F)
|
||||||
where
|
where
|
||||||
T: Clone + 'static,
|
T: Clone + 'static,
|
||||||
A: FnOnce() -> Option<T>,
|
A: FnOnce() -> Option<T> + 'static,
|
||||||
F: FnMut() + 'static,
|
F: FnMut() + 'static,
|
||||||
{
|
{
|
||||||
// SSR 无 DOM,空实现。
|
// SSR 无 DOM,空实现。
|
||||||
|
|||||||
@ -46,6 +46,7 @@ pub struct PaginatedState<T> {
|
|||||||
/// },
|
/// },
|
||||||
/// );
|
/// );
|
||||||
/// ```
|
/// ```
|
||||||
|
#[cfg_attr(not(target_arch = "wasm32"), allow(unused_mut))]
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
pub fn use_paginated<T, P, F, Fut, E>(
|
pub fn use_paginated<T, P, F, Fut, E>(
|
||||||
page: P,
|
page: P,
|
||||||
@ -60,8 +61,8 @@ where
|
|||||||
E: std::fmt::Display + 'static,
|
E: std::fmt::Display + 'static,
|
||||||
{
|
{
|
||||||
let mut loading = use_signal(|| true);
|
let mut loading = use_signal(|| true);
|
||||||
let items = use_signal(Vec::new);
|
let mut items = use_signal(Vec::new);
|
||||||
let total = use_signal(|| 0_i64);
|
let mut total = use_signal(|| 0_i64);
|
||||||
let mut error: Signal<Option<String>> = use_signal(|| None);
|
let mut error: Signal<Option<String>> = use_signal(|| None);
|
||||||
|
|
||||||
use_effect(move || {
|
use_effect(move || {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user