ReactJS:在JSX转换后出现ASCII艺术问题

6

我正在努力让我的React应用程序正确地渲染ASCII艺术。

在执行jsx-transformer之后,我的艺术品失去了格式,并在浏览器中呈现出奇怪的样子。

我的代码:

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Hello World!</title>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/react.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/JSXTransformer.js"></script>
</head>
<body>
  <div id="content"></div>
  <script type="text/jsx">

    var App = React.createClass({
      render: function() {
        return (
          <pre>
            <code>
              +--------+   +-------+    +-------+
              |        |   + ditaa +    |       |
              |  Text  |   +-------+    |diagram|
              |Document|   |!magic!|    |       |
              |        |   |       |    |       |
              +---+----+   +-------+    +-------+
            </code>
          </pre>
        );
      }
    });

    var element = document.getElementById('content');
    React.render(React.createElement(App), element);
  </script>
</body>
</html>

输出:

enter image description here

如果我移除react并直接在html中添加pre代码块,一切都能正常工作。

我在这里做错了什么吗?感谢任何帮助...

更新1: 我不能编辑ASCII艺术。

更新2:我将这个艺术品作为markdown文件收到:

    +--------+   +-------+    +-------+
    |        | --+ ditaa +    |       |
    |  Text  |   +-------+    |diagram|
    |Document|   |!magic!|    |       |
    |        |   |       |    |       |
    +---+----+   +-------+    +-------+

在将Markdown转换为HTML后,这就是我拥有的字符串:

<pre><code>+--------+   +-------+    +-------+
|        | --+ ditaa +    |       |
|  Text  |   +-------+    |diagram|
|Document|   |!magic!|    |       |
|        |   |       |    |       |
+---+----+   +-------+    +-------+
</code></pre>

我仍然使用JSX-loader将HTML转换为JSX。流程是markdown -> html -> jsx。


1
你如何接收ASCII艺术?作为一个带有换行符的单个字符串吗? - Marcus Whybrow
我将它们作为一个Markdown文件接收,并使用markdown-loader将其转换为HTML。生成的HTML是我用来放在问题中的那个。 - Alan Souza
你能否在你的问题中添加你收到的具体字符串,这样我就可以建议一个可行的转换方案。 - Marcus Whybrow
我会尝试的,谢谢 @MarcusWhybrow - Alan Souza
防止JSXTransformer“清理”标记的唯一方法是使用dangerouslySetInnerHTML - Ed Ballot
显示剩余2条评论
4个回答

4

于是我在 Github 上创建了一个 问题,然后 Ben 建议切换到 Babel。

这是更新后可正常工作的代码。

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Hello World!</title>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/react.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.6.15/browser.min.js"></script>
</head>
<body>
  <div id="content"></div>
  <script type="text/babel">

    var App = React.createClass({
      render: function() {
        return (
          <pre>
            <code>{`
              +--------+   +-------+    +-------+
              |        |   + ditaa +    |       |
              |  Text  |   +-------+    |diagram|
              |Document|   |!magic!|    |       |
              |        |   |       |    |       |
              +---+----+   +-------+    +-------+
            `}</code>
          </pre>
        );
      }
    });

    var element = document.getElementById('content');
    React.render(React.createElement(App), element);
  </script>
</body>
</html>

实际上,在jsx-transformer中添加{` ... `}是有效的。但我不确定它为什么有效。

更新:这是因为使用了模板字面量。他们的建议是无论如何都要使用babel,因为JSXTransformer已被弃用。


2

如果遇到无法分离的标签和ASCII字符,您可以使用 dangerouslySetInnerHTML

var App = React.createClass({
  render: function() {

    // My representation of your input ASCII you get from elsewhere
    var inputASCII = [
      "<pre><code>+--------+   +-------+    +-------+",
      "|        |   + ditaa +    |       |",
      "|  Text  |   +-------+    |diagram|",
      "|Document|   |!magic!|    |       |",
      "|        |   |       |    |       |",
      "+---+----+   +-------+    +-------+",
      "</code></pre>",
    ].join('\n');

    // dangerouslySetInnerHTML expects an object like this:
    var wrappedASCII = {__html: inputASCII };

    return <span dangerouslySetInnerHTML={wrappedASCII}></span>;
  }
});

https://jsfiddle.net/yy31xqa3/5/

此功能主要用于与DOM字符串操作库的协作。

不正确使用innerHTML可能会导致跨站脚本攻击(XSS攻击)。 https://facebook.github.io/react/tips/dangerously-set-inner-html.html

仅在您信任ASCII源不会注入<script>标签或其他恶意HTML时才使用此解决方案。


1

尝试在操作前在每行之间添加\n字符:

var App = React.createClass({
  render: function() {
    var ascii = [
      "+--------+   +-------+    +-------+",
      "|        |   + ditaa +    |       |",
      "|  Text  |   +-------+    |diagram|",
      "|Document|   |!magic!|    |       |",
      "|        |   |       |    |       |",
      "+---+----+   +-------+    +-------+",
    ].join('\n');

    return (
      <pre>
        <code>
          {ascii}
        </code>
      </pre>
    );
  }
});

https://jsfiddle.net/yy31xqa3/


很好!但还不够。我无法编辑艺术品,因为它来自我的库之外。我已经更新了问题以反映这一点。谢谢你的帮助! - Alan Souza
我建议您查看我的另一个答案。它更适合您的具体情况。 - Marcus Whybrow

0

尝试手动在每行末尾添加换行符,例如:

          +--------+   +-------+    +-------+<br>
          |        |   + ditaa +    |       |<br>
          |  Text  |   +-------+    |diagram|<br>
          |Document|   |!magic!|    |       |<br>
          |        |   |       |    |       |<br>
          +---+----+   +-------+    +-------+

谢谢@Allen,但我不能这样做,因为我的库从外部接收艺术品,我无法控制。此外,如果我手动添加<br />标签,渲染的HTML将充满span标签。 - Alan Souza
你能否在渲染源文件之前对字符串进行替换?也许尝试用"<br>\n"替换"\n"。 - Allen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接