You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Deno环境下Preact Signal无法在组件中更新的问题

问题描述

控制台能正常打印useeffect日志及API返回的price值,但按钮始终显示Signal初始值first,不会更新为Test Label或API返回的数值。

原因分析
  1. 组件未订阅Signal变化:Preact普通函数组件直接访问signal.value时,不会自动建立Signal更新的订阅关系,Signal变化时不会触发组件重渲染。
  2. 组件未被客户端Hydrate:若Button是静态渲染的HTML(未被客户端Preact实例挂载),即使Signal更新,静态内容也无法动态更新。
解决方案

方案1:自动订阅Signal变化(推荐)

利用useComputed建立对Signal的订阅,信号变化时组件会自动重渲染:

import { h } from 'preact';
import { quoteSignal, useComputed } from '@preact/signals';

export default function Button() {
  const quoteValue = useComputed(() => quoteSignal.value);
  return (
    <button>hello 1 {quoteValue.value}</button>
  );
}

若使用@preact/signals最新版本,直接访问signal.value即可自动订阅,但需确保组件已被客户端hydrate:

import { h } from 'preact';
import { quoteSignal } from '/quoteStore.ts';

export default function Button() {
  return (
    <button>hello 1 {quoteSignal.value}</button>
  );
}

方案2:手动订阅Signal变化

通过useEffect手动监听Signal更新,触发组件强制重渲染:

import { h, useState, useEffect } from 'preact';
import { quoteSignal } from '/quoteStore.ts';

export default function Button() {
  const [, forceRender] = useState({});

  useEffect(() => {
    // 订阅Signal变化,每次更新时强制组件重渲染
    return quoteSignal.subscribe(() => forceRender({}));
  }, []);

  return (
    <button>hello 1 {quoteSignal.value}</button>
  );
}

方案3:确保组件被客户端Hydrate

若使用Preact Islands架构,需将Button组件标记为需hydrate的Island组件(具体方式依框架而定,如Astro中添加client:load指令),确保客户端挂载组件,使其能响应动态变化。

内容的提问来源于stack exchange,提问作者NimChimpsky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 03:07:34