首页 > 解决方案 > 如何将一小部分 Markdown 解析为 React 组件?

问题描述

我有一个非常小的 Markdown 子集以及一些我想解析为 React 组件的自定义 html。例如,我想将以下字符串变为:

hello *asdf* *how* _are_ you !doing! today

进入以下数组:

[ "hello ", <strong>asdf</strong>, " ", <strong>how</strong>, " ", <em>are</em>, " you ", <MyComponent onClick={this.action}>doing</MyComponent>, " today" ]

然后从 React 渲染函数返回它(React 会将数组正确渲染为格式化的 HTML)

基本上,我想让用户选择使用非常有限的一组 Markdown 将他们的文本转换为样式组件(在某些情况下是我自己的组件!)

危险地设置InnerHTML是不明智的,我不想引入外部依赖,因为它们都很重,我只需要非常基本的功能。

我目前正在做这样的事情,但它非常脆弱,并不适用于所有情况。我想知道是否有更好的方法:

function matchStrong(result, i) {
  let match = result[i].match(/(^|[^\\])\*(.*)\*/);
  if (match) { result[i] = <strong key={"ms" + i}>{match[2]}</strong>; }
  return match;
}

function matchItalics(result, i) {
  let match = result[i].match(/(^|[^\\])_(.*)_/); // Ignores \_asdf_ but not _asdf_
  if (match) { result[i] = <em key={"mi" + i}>{match[2]}</em>; }
  return match;
}

function matchCode(result, i) {
  let match = result[i].match(/(^|[^\\])```\n?([\s\S]+)\n?```/);
  if (match) { result[i] = <code key={"mc" + i}>{match[2]}</code>; }
  return match;
}

// Very brittle and inefficient
export function convertMarkdownToComponents(message) {
  let result = message.match(/(\\?([!*_`+-]{1,3})([\s\S]+?)\2)|\s|([^\\!*_`+-]+)/g);

  if (result == null) { return message; }

  for (let i = 0; i < result.length; i++) {
    if (matchCode(result, i)) { continue; }
    if (matchStrong(result, i)) { continue; }
    if (matchItalics(result, i)) { continue; }
  }

  return result;
}

这是我之前的问题,它导致了这个问题。

标签: javascriptarraysregexreactjsmarkdown

解决方案


看起来您正在寻找一个非常基本的小型解决方案。不是“超级怪物”之类的react-markdown-it:)

我想向您推荐https://github.com/developit/snarkdown,它看起来非常轻巧且美观!只有 1kb 并且非常简单,如果您需要任何其他语法功能,您可以使用它并对其进行扩展。

支持的标签列表https://github.com/developit/snarkdown/blob/master/src/index.js#L1

更新

刚注意到反应组件,一开始就错过了。所以这对你很好,我相信以图书馆为例,并实现你的自定义所需组件来完成它,而不会危险地设置 HTML。图书馆很小很清楚。玩得开心!:)


推荐阅读