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

