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

如何在Next.js中将Draft.js区块渲染为React组件

解决Draft.js转HTML时替换为Next/Image组件的方案

核心思路

draftjs-to-html、draft-js-export-html这类库的作用是生成HTML字符串,直接返回React组件会被转为[Object object]——因为库只接受字符串类型的渲染结果。正确的做法是分两步处理:

  1. 先转成带识别标记的标准HTML字符串
  2. 在React渲染阶段解析HTML,将目标img标签替换为Next/Image组件

步骤1:生成带标记的HTML字符串

修改draftjs-to-html的自定义渲染器,给图片标签添加自定义data属性,方便后续识别:

import draftToHtml from 'draftjs-to-html';

const customRenderers = {
  image: (block) => {
    const { src, alt = '' } = block.data;
    // 给img标签添加自定义标记属性
    return `<img data-next-image src="${src}" alt="${alt}" />`;
  }
};

// 从数据库取出的EditorState JSON先转为EditorState,再生成HTML
const htmlContent = draftToHtml(editorState.getCurrentContent(), customRenderers);

步骤2:解析HTML并替换为Next/Image组件

使用react-html-parser库解析HTML字符串,在解析过程中替换目标img标签:

import React from 'react';
import Image from 'next/image';
import parse from 'react-html-parser';

const renderOptimizedContent = (html) => {
  return parse(html, {
    transform: (node) => {
      // 匹配我们标记的img标签
      if (node.type === 'tag' && node.name === 'img' && node.attribs['data-next-image']) {
        const { src, alt = '' } = node.attribs;
        return (
          <Image
            src={src}
            alt={alt}
            fill // 若使用fill模式,需确保父容器为相对定位
            className="blog-image"
            sizes="100vw"
            priority={false}
          />
        );
      }
      // 其他标签保持原样渲染
      return node;
    }
  });
};

// 组件中使用示例
const BlogPost = ({ editorStateJson }) => {
  // 此处省略将JSON转为EditorState的逻辑,可使用convertFromRaw
  const htmlContent = draftToHtml(editorState.getCurrentContent(), customRenderers);
  
  return (
    <div className="blog-post-content">
      {renderOptimizedContent(htmlContent)}
    </div>
  );
};

export default BlogPost;

注意事项

  • 确保在next.config.js中配置图片域名白名单,避免Next/Image报错:
    /** @type {import('next').NextConfig} */
    const nextConfig = {
      images: {
        remotePatterns: [
          {
            protocol: 'https',
            hostname: 'your-image-host.com', // 替换为你的图片域名
            port: '',
            pathname: '/**',
          },
        ],
      },
    };
    
    module.exports = nextConfig;
    
  • Next/Image的尺寸配置:根据布局需求选择width/height固定尺寸,或fill配合父容器相对定位
  • 若不想额外引入react-html-parser,也可以自己编写正则表达式替换img标签为React组件的JSX字符串,再结合组件渲染,但这种方式复杂度更高,不如使用成熟的解析库

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 11:18:21