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

SolidJS技术问题:如何根据组件ID更新对应props.error?

SolidJS + Zod 表单验证:无法更新InputCustom组件的error prop问题

问题根源

你现在通过document.getElementById手动设置DOM属性的操作,完全绕开了SolidJS的响应式系统。SolidJS只会追踪自身响应式状态的变化,这种直接DOM操作不会触发组件重新渲染,所以InputCustom的error prop始终是空的。

正确解决方案

1. 父组件:用响应式状态管理错误信息

在父组件里创建响应式状态来存储各字段的错误信息,推荐用createStore(适配字段名-错误信息的键值对结构),提交验证时把Zod的错误映射到这个状态里,再通过props传递给子组件。

修改后的父组件代码:

import { createStore } from 'solid-js';

// 初始化空的字段错误状态
const [fieldErrors, setFieldErrors] = createStore<Record<string, string>>({});

const handleSubmit = () => {
    try {
        validateForm.parse(form);
        // 验证通过时清空所有错误
        setFieldErrors({});
    } catch (error: unknown) {
        const { errors } = error as ZodError;
        // 把Zod错误转换成字段名对应错误信息的对象
        const newErrors = errors.reduce((acc, err) => {
            const fieldName = err.path[0] as string;
            acc[fieldName] = err.message;
            return acc;
        }, {} as Record<string, string>);
        // 更新响应式错误状态
        setFieldErrors(newErrors);
    }
};

return (
    <form>
        <InputCustom
            type='email'
            id='email'
            name='email'
            value={form.email}
            onInput={...}
            class={styles.email}
            // 传递对应字段的错误
            error={fieldErrors.email}
        >
            Email
        </InputCustom>
        
        {/* 其他输入组件同理 */}
        <InputCustom
            type='text'
            id='username'
            name='username'
            value={form.username}
            onInput={...}
            error={fieldErrors.username}
        >
            Username
        </InputCustom>
        ... // 更多输入组件
    </form>
);

2. 子组件:正确响应error prop变化

子组件里直接使用响应式的error prop即可,同时可以优化渲染逻辑,只在有错误时显示提示:

修改后的子组件代码:

const InputCustom: Component<ComponentProps<'input'> & { error?: string }> = props => {
    const { class: className, children, error, ...rest } = props;

    return (
        <div class={`${styles.field} ${className || ''}`}>
            <label for={props.id}>{children}</label>
            <input {...rest} class='sanded' />
            {/* 仅当error存在时渲染提示,避免空标签 */}
            {error && <small>{error}</small>}
        </div>
    );
};

额外优化建议

  • 可以给输入框添加onBlur事件,在用户离开输入框时单独验证该字段,实时更新错误,提升体验。
  • 如果表单字段较多,可封装一个自定义Hook统一处理表单状态、验证逻辑,减少重复代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 02:23:15