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

为何@legendapp/state的<Computed>组件状态变化时不重渲染?

Legend State中Computed组件不随Observable状态更新重渲染的问题

我在探索Legend State时遇到一个问题:当Observable状态变化时,<Computed>组件不会触发重渲染,但<Show>组件能正常工作。

预期效果是每秒切换showChild状态,状态变化后<Show>组件正常重渲染,但<Computed>组件没有反应。

我的代码如下:

import {Computed, Show, useObservable} from '@legendapp/state/react'
import { useInterval } from '../utils/hooks'

function LegendStateModal() {
    const showChild = useObservable(false)
    // const text = useComputed(() => showChild.get() ? 'true' : 'false')
  
    useInterval(() => {
      showChild.set((v) => !v)
    }, 1000)
  
    return (
      <div className='flex flex-col'>
        <span>Showing child: </span>
  
        <Computed>
          <span
            className={showChild.get() ? 'text-red-900' : 'text-green-900'}
          >
            {showChild.get() ? 'true' : 'false'}
          </span>
        </Computed>
  
        <Show if={showChild}>
          <div>Child element</div>
        </Show>
      </div>
    )
  }

export default LegendStateModal;

问题原因

<Computed>组件的核心是依赖追踪,它需要接收一个函数作为子元素,通过函数内部对Observable状态的访问来建立依赖关系。你当前的写法是直接在<Computed>中嵌套JSX,内部的showChild.get()调用无法被Legend State的依赖系统捕获,因此状态变化时不会触发重渲染。

而<Show>组件内部已经封装了完整的依赖追踪逻辑,直接传入Observable就能自动响应状态变化。

解决方案

方案1:给Computed传递函数子元素

这是<Computed>组件的标准用法,将JSX包裹在函数中传入:

import {Computed, Show, useObservable} from '@legendapp/state/react'
import { useInterval } from '../utils/hooks'

function LegendStateModal() {
    const showChild = useObservable(false)
  
    useInterval(() => {
      showChild.set((v) => !v)
    }, 1000)
  
    return (
      <div className='flex flex-col'>
        <span>Showing child: </span>

        <Computed>
          {() => (
            <span
              className={showChild.get() ? 'text-red-900' : 'text-green-900'}
            >
              {showChild.get() ? 'true' : 'false'}
            </span>
          )}
        </Computed>
  
        <Show if={showChild}>
          <div>Child element</div>
        </Show>
      </div>
    )
  }

export default LegendStateModal;

方案2:使用useComputed钩子提前计算值

如果需要复用计算结果,可以用useComputed创建计算Observable,再在组件中访问其值:

import {Computed, Show, useObservable, useComputed} from '@legendapp/state/react'
import { useInterval } from '../utils/hooks'

function LegendStateModal() {
    const showChild = useObservable(false)
    const displayText = useComputed(() => showChild.get() ? 'true' : 'false')
    const textClass = useComputed(() => showChild.get() ? 'text-red-900' : 'text-green-900')
  
    useInterval(() => {
      showChild.set((v) => !v)
    }, 1000)
  
    return (
      <div className='flex flex-col'>
        <span>Showing child: </span>

        <span className={textClass.get()}>{displayText.get()}</span>
  
        <Show if={showChild}>
          <div>Child element</div>
        </Show>
      </div>
    )
  }

export default LegendStateModal;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 10:44:57