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

React Hook Form中blockquote输入后验证提示不消失,求技术指导

React Hook Form 配合 contentEditable blockquote 验证不更新的问题解决

问题根源

  1. 非标准表单控件不兼容register:blockquote不是原生表单元素,即使加上contentEditable='true',React Hook Form的register方法也无法自动监听它的输入变化、同步值,导致验证状态无法实时更新。
  2. 重复字段名冲突:多个blockquote都注册为blogcode,RHF无法区分不同输入项,字段值会被相互覆盖,验证逻辑混乱。
  3. contentEditable不支持value属性:你给blockquote设置的value属性无效,原生contentEditable元素的内容是通过innerText/innerHTML控制的。

解决方案

用React Hook Form的Controller组件手动管控非标准表单控件,同时调整字段命名为数组格式区分多个输入项:

1. 导入Controller

首先在顶部导入Controller:

import { useForm, Controller } from "react-hook-form";

2. 修改字段注册与渲染逻辑

替换原来的map渲染部分,用Controller包裹blockquote,并使用数组字段名:

const { control, formState: { errors } } = useForm();

<div className='row'>
  {createCode.map((code, idx) => {
    const fieldName = `blogcode[${idx}]`; // 用数组索引区分每个字段
    return (
      <div key={`${code}-${idx}`} className="dCodeArea">
        <button type="button" onClick={() => handleRemoveCode(idx)} className="closeElement">
          X
        </button>
        <Controller
          name={fieldName}
          control={control}
          rules={{
            required: "Blog code is required !",
            minLength: {
              value: 5,
              message: "Minimum length of code is 5"
            }
          }}
          render={({ field: { onChange, value } }) => (
            <blockquote
              contentEditable='true'
              className="codehighlight"
              onInput={(e) => onChange(e.currentTarget.innerText)} // 手动触发onChange同步值
              dangerouslySetInnerHTML={{ __html: value || "" }} // 用dangerouslySetInnerHTML设置内容
              placeholder="Enter your code here"
            />
          )}
        />
        <span className="validationmsg">
          {errors.blogcode?.[idx] && <span>{errors.blogcode[idx].message}</span>}
        </span>
      </div>
    );
  })}
</div>

3. 进阶优化:用useFieldArray管理动态输入项

如果需要动态添加/移除输入项,推荐用RHF的useFieldArray替代自己维护的createCode状态,更贴合RHF的逻辑:

const { control, formState: { errors }, useFieldArray } = useForm({
  defaultValues: {
    blogcode: [""] // 默认一个空输入项
  }
});

const { fields, append, remove } = useFieldArray({
  control,
  name: "blogcode"
});

// 移除按钮直接调用remove(idx),添加按钮调用append("")

关键注意点

  • contentEditable元素的placeholder需要自定义样式实现,原生不支持,比如当内容为空时显示占位文本。
  • 使用dangerouslySetInnerHTML时要注意XSS风险,如果输入内容是用户可控的,建议做转义处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 11:25:30