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

如何在React中映射并获取Froala编辑器添加的表单输入数据?

解决React中Froala编辑器生成表单无法获取输入数据的问题

因为通过dangerouslySetInnerHTML或FroalaEditorView渲染的表单元素不属于React虚拟DOM管控范围,React无法直接通过受控组件方式绑定state,需要手动操作DOM来收集输入数据,以下是两种可行方案:

方案1:监听表单提交事件,一次性收集所有数据

给渲染表单的容器添加ref,在组件挂载后监听表单的submit事件,手动遍历所有表单元素获取值:

import { useRef, useEffect } from 'react';

function OfferLetterView({ content }) {
  const formContainerRef = useRef(null);

  useEffect(() => {
    const handleSubmit = (e) => {
      e.preventDefault();
      // 收集所有表单数据
      const formData = new FormData(e.target);
      // 转为普通对象
      const formValues = Object.fromEntries(formData.entries());
      console.log('候选人提交的数据:', formValues);
      // 这里可以将数据发送到后端或做其他处理
    };

    const formElement = formContainerRef.current.querySelector('form');
    if (formElement) {
      formElement.addEventListener('submit', handleSubmit);
      // 清理监听
      return () => formElement.removeEventListener('submit', handleSubmit);
    }
  }, [content]);

  return (
    <div className="mt-20" ref={formContainerRef}>
      <div dangerouslySetInnerHTML={{ __html: content }} />
    </div>
  );
}

方案2:实时监听输入变化,同步更新state

如果需要实时获取输入数据,可以遍历所有输入元素,给它们添加change或input事件监听:

import { useRef, useEffect, useState } from 'react';

function OfferLetterView({ content }) {
  const formContainerRef = useRef(null);
  const [formValues, setFormValues] = useState({});

  useEffect(() => {
    const updateFormValues = (element) => {
      const name = element.name;
      let value;
      if (element.type === 'radio') {
        value = element.checked ? element.value : undefined;
      } else if (element.type === 'checkbox') {
        value = element.checked;
      } else {
        value = element.value;
      }
      setFormValues(prev => ({ ...prev, [name]: value }));
    };

    const setupEventListeners = () => {
      const inputElements = formContainerRef.current.querySelectorAll('input, textarea, select');
      inputElements.forEach(el => {
        el.addEventListener('change', () => updateFormValues(el));
        // 文本框可以监听input事件实时更新
        if (el.type === 'text' || el.tagName === 'TEXTAREA') {
          el.addEventListener('input', () => updateFormValues(el));
        }
      });

      // 清理所有监听
      return () => {
        inputElements.forEach(el => {
          el.removeEventListener('change', () => updateFormValues(el));
          if (el.type === 'text' || el.tagName === 'TEXTAREA') {
            el.removeEventListener('input', () => updateFormValues(el));
          }
        });
      };
    };

    // 内容更新时重新设置监听
    const cleanup = setupEventListeners();
    return cleanup;
  }, [content]);

  return (
    <div className="mt-20" ref={formContainerRef}>
      <div dangerouslySetInnerHTML={{ __html: content }} />
      {/* 可以实时展示收集到的数据 */}
      <pre>{JSON.stringify(formValues, null, 2)}</pre>
    </div>
  );
}

注意事项

  • 确保Froala编辑器生成的表单元素都带有name属性,否则无法通过FormData或name属性识别字段
  • 如果表单中有多个单选按钮,要保证同一组单选按钮的name属性一致
  • 每次content更新时,需要重新绑定事件监听,因为DOM元素会被重新渲染

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 12:28:14