Draft.js 中如何正确处理空格和换行的保存问题?

上官照涵 阅读 6

我在用 Draft.js 做一个富文本编辑器,内容保存到后端时发现连续空格和换行经常被吃掉。比如用户输入了多个空格或回车,转成 HTML 后就变成一个或者直接没了,这体验很不好。

我试过用 convertToRaw 再 JSON.stringify 存原始内容,但前端展示时还是不对。下面是我转换 HTML 的代码:

const contentState = editorState.getCurrentContent();
const html = draftToHtml(convertToRaw(contentState));
// 保存 html 到数据库
我来解答 赞 1 收藏
二维码
手机扫码查看
1 条解答
光耀 Dev
这个问题挺常见的,我来帮你分析一下。

问题根源有两个层面:

第一层是 HTML 渲染时的样式问题。你保存的 HTML 内容在页面展示时,如果没有设置正确的 CSS 样式,连续的空格和换行会被浏览器当作普通空白字符处理,多个空格会被合并成一个。

第二层是 draftToHtml 转换时的配置问题。默认配置下,它不会把空格转换成   来保证显示。

解决方案分两步走:

第一步:给显示容器加上 CSS 样式

这是最关键的一步。你需要让显示富文本内容的地方保留原始的空格和换行:

.rich-text-content {
white-space: pre-wrap;
word-wrap: break-word;
}


white-space: pre-wrap 这个属性的作用就是告诉浏览器:保留空格和换行,但是超长时自动换行。如果你希望完全不换行,可以用 pre,但大多数场景 pre-wrap 更好用。

第二步:调整 draftToHtml 的配置

如果第一步之后还是有问题,可以在转换时做额外处理:

import draftToHtml from 'draftjs-to-html';
import { convertToRaw } from 'draft-js';

const contentState = editorState.getCurrentContent();

// 使用 convertToRaw 获取原始内容
const rawContent = convertToRaw(contentState);

// 转换时启用实体处理
const html = draftToHtml(rawContent, {
// 处理块级元素的样式
blockStyleFn: (block) => {
const type = block.getType();
if (type === 'blockquote') {
return { style: { borderLeft: '3px solid #ccc', paddingLeft: '10px' } };
}
return null;
},
// 处理实体(比如链接、图片等)
entityStyleFn: (entity) => {
const entityType = entity.getType();
if (entityType === 'LINK') {
return {
element: 'a',
attributes: {
href: entity.getData().url,
target: '_blank'
}
};
}
return null;
}
}, true, true);

// 保存到数据库
saveToDatabase(html);


关于你提到的"转成 HTML 后空格没了"的问题,还有一个可能的坑:

如果你是在 textarea 里显示这个 HTML,那确实会出问题,因为 textarea 不支持 HTML。确保你的 HTML 是渲染到一个 div 或者其他支持 HTML 的容器里:

// 错误用法 - textarea 不会解析 HTML 标签
<textarea value={html} />

// 正确用法 - div 会渲染 HTML
<div dangerouslySetInnerHTML={{ __html: html }} />


最后提醒一点:

如果你用的是 React 18+,用 dangerouslySetInnerHTML 时要小心点,虽然这里没有安全问题因为内容是用户自己输入的。

你试试加上 CSS 那一步能不能解决?如果还不行,把你的显示层代码也贴出来,我帮你看看具体是哪里卡住了。
点赞
2026-03-12 12:31