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

Solid.js中按钮点击状态作为Props传递给子组件不更新问题求助

问题:Solid.js中子组件无法跟踪父组件传递的props变更

我在Solid.js中尝试将按钮点击触发的状态变更作为props传递给子组件并跟踪该变化,但目前实现无法正常工作——createEffect钩子仅在Button组件首次渲染时触发,后续按钮点击后无法更新showDot的值。

父组件代码

const [showShoppingCart, setShowShoppingCart] = createSignal<boolean>(false)

const showCart = () => {
        setShowShoppingCart(!showShoppingCart())
    }

 <Button
    id={actionItem.id}
    iconName={actionItem.icon}
    iconClassName={actionItem.className}
    onClick={() => {
                   actionItem.icon === 'Search'
                   ? showSearchPanel(actionItem)
                   : actionItem.icon === 'User'
                   ? openSubMenu()
                   : actionItem.icon === 'Bucket'
                   ? showCart()
                   : ''
              }}
    showSelectedDot={actionItem.icon === 'Bucket' && showShoppingCart()}
  ></Button>

子组件代码

const Button = ({iconName, label, onClick, className = 'button-primary', id, iconClassName, showSelectedDot = false}: ButtonProps) => {
    const [showDot, setShowDot] = createSignal(false);
    createEffect(() => {
        console.log("show selected dot",showSelectedDot);
        setShowDot(showSelectedDot)
    })
    const icon = useIcon()
    const ButtonIcon = iconName && icon.get(iconName)
    return (
        <button class={`button ${iconName ? 'button-icon' : className}`} id={id} onClick={onClick}>
            {iconName && ButtonIcon ? <ButtonIcon class={`webstv-icon webstv-btn-icon ${iconClassName}`} /> : label}
            {showDot() && <div class='notification-dot'></div>}
        </button>
    )
}

export default Button

解决方案

核心原因

Solid.js的响应式依赖追踪需要明确访问响应式值的getter逻辑。你当前在createEffect中直接使用showSelectedDot原始值,没有建立起响应式依赖,所以props更新时effect不会重新执行。

方案1:直接使用props值(推荐)

Solid.js的props本身就是响应式的,完全不需要额外维护子组件内部的showDot信号,直接在模板中使用showSelectedDot即可:

const Button = ({iconName, label, onClick, className = 'button-primary', id, iconClassName, showSelectedDot = false}: ButtonProps) => {
    const icon = useIcon()
    const ButtonIcon = iconName && icon.get(iconName)
    return (
        <button class={`button ${iconName ? 'button-icon' : className}`} id={id} onClick={onClick}>
            {iconName && ButtonIcon ? <ButtonIcon class={`webstv-icon webstv-btn-icon ${iconClassName}`} /> : label}
            {showSelectedDot && <div class='notification-dot'></div>}
        </button>
    )
}

方案2:保留子组件内部信号(仅当需要额外逻辑时)

如果必须维护showDot信号,要确保在createEffect中访问showSelectedDot的响应式值,以此建立依赖关系:

const Button = ({iconName, label, onClick, className = 'button-primary', id, iconClassName, showSelectedDot = false}: ButtonProps) => {
    const [showDot, setShowDot] = createSignal(false);
    createEffect(() => {
        // 访问props的响应式值,触发依赖追踪
        const currentValue = showSelectedDot;
        console.log("show selected dot", currentValue);
        setShowDot(currentValue);
    })
    const icon = useIcon()
    const ButtonIcon = iconName && icon.get(iconName)
    return (
        <button class={`button ${iconName ? 'button-icon' : className}`} id={id} onClick={onClick}>
            {iconName && ButtonIcon ? <ButtonIcon class={`webstv-icon webstv-btn-icon ${iconClassName}`} /> : label}
            {showDot() && <div class='notification-dot'></div>}
        </button>
    )
}

解释:在createEffect中读取showSelectedDot的值时,Solid.js会自动将该effect注册为该props的依赖项,当父组件中showShoppingCart更新导致showSelectedDot变化时,effect会重新执行,进而更新showDot的值。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 05:20:34