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

使用@preact/signals-react修改对象属性组件不重新渲染问题

问题原因分析:@preact/signals-react修改对象属性后组件不渲染

问题重现

你的代码中,通过useSignal创建了包含嵌套属性的对象信号,修改ob.value.x时控制台能看到值变化,但组件不会重新渲染:

import { useSignal } from '@preact/signals-react'

function App() {
    const ob = useSignal({ x: 0 })

    setInterval(() => {
        ob.value.x = Math.random()
        console.log(ob.value)
    }, 1000)

    return <>x : {ob.value.x}</>
}

export default App

核心原因

@preact/signals-react的自动响应依赖编译时的Babel转换,它需要@preact/signals-react-transform插件识别组件中对信号属性的访问,以此建立依赖追踪关系。

而默认的Create React App(CRA)配置没有集成这个Babel插件,导致组件无法感知信号嵌套属性的变化——编译阶段未对ob.value.x的访问做特殊处理,信号更新时无法触发组件重新渲染。

为什么react-app-rewired能解决问题

react-app-rewired允许你在不eject CRA的前提下,修改底层的Webpack和Babel配置。你可以手动将@preact/signals-react-transform添加到Babel插件列表中,编译时就能正确追踪信号的嵌套属性访问,属性变化时组件就能同步重新渲染。

替代解决方案(无需修改CRA配置)

如果不想用react-app-rewired,也可以通过以下方式让组件响应变化:

  • 替换整个信号对象:触发信号的整体更新,让组件感知到变化
    setInterval(() => {
        ob.value = { ...ob.value, x: Math.random() }
    }, 1000)
    
  • 使用useComputed追踪嵌套属性:通过计算属性建立依赖
    import { useSignal, useComputed } from '@preact/signals-react'
    
    function App() {
        const ob = useSignal({ x: 0 })
        const x = useComputed(() => ob.value.x)
    
        setInterval(() => {
            ob.value.x = Math.random()
        }, 1000)
    
        return <>x : {x}</>
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 03:59:54