SolidJS:使用可复用组件时输入框值不更新的原因
问题原因及解决方案
核心原因
你使用的是SolidJS框架,问题出在自定义组件的props处理逻辑上:
- SolidJS的原生
<input>元素会自动订阅响应式值的变化,当payload.deviceId更新时,原生输入框能感知并同步更新。 - 但自定义组件中直接解构
valueprop时,会获取到初始值的静态副本,无法跟踪后续props.value的变化——因为SolidJS的组件props是响应式代理对象,直接解构会丢失响应性绑定。
解决方案
以下三种方式都能解决这个问题:
方案1:直接使用props对象访问属性(最直观)
不解构props,直接通过props.xxx访问属性,确保始终获取最新的响应式值:
interface DeviceFormInputProps extends JSX.InputHTMLAttributes<HTMLInputElement> { label: string; value: string | number; type?: string; disabled?: boolean; onInput?: (e: InputEvent) => void; } const DeviceFormInput: Component<DeviceFormInputProps> = (props) => { return ( <div> <label class="mb-1 block text-sm font-medium text-gray-700"> {props.label} </label> <input onInput={props.onInput} disabled={props.disabled ?? false} type={props.type ?? "text"} value={props.value} /> </div> ); };
方案2:使用$props辅助函数解构(保持代码简洁)
通过SolidJS提供的$props工具解构props,自动保留响应性:
import { $props } from "solid-js"; interface DeviceFormInputProps extends JSX.InputHTMLAttributes<HTMLInputElement> { label: string; value: string | number; type?: string; disabled?: boolean; onInput?: (e: InputEvent) => void; } const DeviceFormInput: Component<DeviceFormInputProps> = () => { const { label, value, type = "text", disabled = false, onInput } = $props<DeviceFormInputProps>(); return ( <div> <label class="mb-1 block text-sm font-medium text-gray-700"> {label} </label> <input onInput={onInput} disabled={disabled} type={type} value={value} /> </div> ); };
方案3:用createMemo手动创建响应式值
将解构后的value包装为响应式记忆值,强制跟踪变化:
import { createMemo } from "solid-js"; interface DeviceFormInputProps extends JSX.InputHTMLAttributes<HTMLInputElement> { label: string; value: string | number; type?: string; disabled?: boolean; onInput?: (e: InputEvent) => void; } const DeviceFormInput: Component<DeviceFormInputProps> = ({ label, value, type = "text", disabled = false, onInput, }) => { const reactiveValue = createMemo(() => value); return ( <div> <label class="mb-1 block text-sm font-medium text-gray-700"> {label} </label> <input onInput={onInput} disabled={disabled} type={type} value={reactiveValue()} /> </div> ); };
内容的提问来源于stack exchange,提问作者Kelvin Anderson
相关产品推荐
相关产品推荐

