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

Preact Signals:计算信号能否像函数一样接收参数?

问题分析与解决方案

为什么会报错?

computed 的回调函数不接受参数,它只能通过依赖其他信号的 .value 来响应变化,最终返回的是一个 Signal 实例,而非可调用的函数。所以直接执行 textAndData(num) 会触发 TypeError: textAndData is not a function。

可行实现方式(统一管理模块级信号)

方案1:用额外信号存储动态参数

将需要传入的变量封装成模块级信号,让 computed 依赖这个信号的 .value,组件只需更新信号值即可触发计算:

import { render } from "preact";
import { signal, computed } from "@preact/signals";

// 模块级统一管理所有信号
const text = signal('This is changed on client');
const numSignal = signal(0); // 新增信号存储动态参数

// computed 依赖 numSignal.value,无需传参
const textAndData = computed(() => {
  const data = `And this data is read on the server: ${numSignal.value}`;
  return `${text.value}. ${data}`;
});

function Result() {
  // 组件内更新动态参数信号
  numSignal.value = 3;
  return (
    <> {textAndData.value} </>
  );
}

render(<Result />, document.getElementById("app"));

方案2:封装工厂函数创建组件级computed

如果不同组件需要传入不同的静态/响应式参数,可以在模块内导出工厂函数,统一管理计算逻辑,组件调用函数生成对应computed:

import { render } from "preact";
import { signal, computed, useSignal } from "@preact/signals";

// 模块级基础信号
const text = signal('This is changed on client');

// 统一管理计算逻辑的工厂函数
export function createTextAndData(numSource) {
  return computed(() => {
    // 支持静态值或信号的.value
    const num = typeof numSource.value === 'undefined' ? numSource : numSource.value;
    const data = `And this data is read on the server: ${num}`;
    return `${text.value}. ${data}`;
  });
}

function Result() {
  // 组件内用静态值或组件级信号创建computed
  const num = useSignal(3);
  const textAndData = createTextAndData(num);
  
  return (
    <>
      {textAndData.value}
      <button onClick={() => num.value++}>Increment</button>
    </>
  );
}

render(<Result />, document.getElementById("app"));

核心思路

computed 的设计是依赖追踪响应式信号,而非接收调用参数。要实现动态参数传入,要么将参数转为信号让computed依赖,要么通过工厂函数封装computed的创建逻辑,既保证信号统一管理,又满足组件的动态需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 21:23:13