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

React函数式组件中如何使用Draft.js编辑器处理及存储输入数据

问题修正方案

你当前代码存在3个核心错误,按以下步骤修改即可正常获取编辑器内容、存入数据库:

  • useState用法错误:未做数组解构,且编辑器初始值不能是空字符串,必须使用draft-js提供的EditorState.createEmpty()初始化
  • 组件事件绑定错误:react-draft-wysiwyg的Editor组件不通过onChange回传状态,需要绑定专属的onEditorStateChange事件,同时必须把当前状态传入组件的editorState属性,否则编辑器是不受控状态,拿不到输入内容
  • 存储逻辑缺失:draft-js内部使用Immutable结构存储内容,不能直接把EditorState对象存到数据库,需要转成通用的HTML字符串或者标准Raw JSON结构再存储

具体实现步骤

  1. 补充缺失的导入:如果需要转HTML存储,先安装依赖npm i draftjs-to-html,然后在文件头部补全导入项
  2. 修正状态定义,为标题、选中城市、文件上传也补充对应的受控状态
  3. 给Editor组件正确绑定状态和变更事件
  4. 提交时把编辑器内容转成可存储的格式,和其他表单字段一起提交到后端

修正后的完整代码

import React, { useContext, useState } from 'react'
import Modal from 'react-bootstrap/Modal';
import Button from 'react-bootstrap/Button';
import { Editor } from 'react-draft-wysiwyg';
import { EditorState, convertToRaw, convertFromRaw, ContentState } from 'draft-js';
import draftToHtml from 'draftjs-to-html';
import "react-draft-wysiwyg/dist/react-draft-wysiwyg.css";
import cityContext from "../context/cities/CityContext"

export default function CreatePost(props) {
    const cities = useContext(cityContext);
    // 编辑器状态,初始化为空内容
    const [editorState, setEditorState] = useState(EditorState.createEmpty());
    // 其他表单字段状态
    const [title, setTitle] = useState("");
    const [selectedCity, setSelectedCity] = useState("");
    const [uploadFile, setUploadFile] = useState(null);

    // 编辑器内容变更回调
    const onEditorStateChange = (newEditorState) => {
        setEditorState(newEditorState);
    }

    // 提交表单逻辑
    const handleSubmit = () => {
        // 方式1:转成HTML字符串,可直接存入数据库,纯展示时不需要加载编辑器
        const editorContentHtml = draftToHtml(convertToRaw(editorState.getCurrentContent()));
        // 方式2:转成Raw JSON格式存储,后续重新加载编辑时不会丢失格式
        // const editorContentRaw = JSON.stringify(convertToRaw(editorState.getCurrentContent()));

        // 组装所有提交数据
        const submitData = {
            title,
            city: selectedCity,
            cover: uploadFile,
            content: editorContentHtml
        }
        // 此处写接口请求逻辑,将submitData传入后端存库即可
        console.log("提交的数据:", submitData);
        props.onHide();
    }

    return (
        <div>
            <Modal className="text-center"
                {...props}
                size="lg"
                centered
            >
                <Modal.Body >
                    <input 
                        type="text" 
                        className="form-control my-2 p-3" 
                        placeholder='Enter title of the text'
                        value={title}
                        onChange={(e) => setTitle(e.target.value)}
                    />
                    <input 
                        type="file" 
                        className="form-control my-2 p-3" 
                        onChange={(e) => setUploadFile(e.target.files[0])}
                    />
                    <select 
                        className="form-control cityField p-3 my-2" 
                        value={selectedCity}
                        onChange={(e) => setSelectedCity(e.target.value)}
                    >
                        <option className='cityField' value="">--select city for the article--</option>
                        {cities.map(cityObj => <option key={cityObj.city} value={cityObj.city} className='cityField' >
                            {cityObj.city}</option>)}
                    </select>

                    <Editor 
                        className="editor"
                        editorState={editorState}
                        onEditorStateChange={onEditorStateChange}
                    />

                </Modal.Body>
                <Modal.Footer>
                    <Button className="btn btn-danger form-control" onClick={props.onHide}>cancel</Button>
                    <Button className="btn btn-success form-control" onClick={handleSubmit}>submit</Button>
                </Modal.Footer>
            </Modal>
        </div>
    )
}

补充说明

  • 如果选择存Raw JSON格式,后续回显到编辑器时,只需要用EditorState.createWithContent(convertFromRaw(JSON.parse(数据库存储的raw内容)))作为editorState的初始值即可,不会丢失任何格式
  • 如果选择存HTML格式,前端纯展示内容时可以直接用dangerouslySetInnerHTML={{__html: 数据库存储的html字符串}}渲染,不需要额外引入编辑器
  • 编辑器的图片上传、工具栏自定义配置可以根据自身需求在Editor组件上加对应props实现

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 20:21:38