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
相关产品推荐
相关产品推荐

