如何将字符串转换为 jsx?

IT技术 reactjs react-jsx
2021-03-30 01:44:43

我将如何获取一个字符串,并将其转换为jsx例如,如果我从 a 中引入一个字符串textarea,我如何将其转换为一个React元素;

var jsxString = document.getElementById('textarea').value;

我将使用什么过程在客户端转换它?是否可以?

6个回答

您可以考虑使用 React 属性dangerouslySetInnerHTML

class YourComponent{
  render() {
    someHtml = '<div><strong>blablabla<strong><p>another blbla</p/></div>'
     
    return (
      <div className="Container" dangerouslySetInnerHTML={{__html: someHtml}}></div>
    )
  }
}
dangerouslySetInnerHTML不允许在标签内使用驼峰式名称,它会将它们转换为小写。这是因为它适用于 html 标签。
2021-05-25 01:44:43
警告dangerouslySetInnerHTML易受 XSS 攻击。
2021-05-29 01:44:43
这在渲染React 组件的 Don't see your post <Link to=\"/add-professor\">Add Your Post</Link>情况下<Link>不起作用在这种情况下没有得到应有的渲染
2021-06-18 01:44:43

就个人而言,我喜欢这样做,就像在之前的答案中建议dangerouslySetInnerHTML在 JSX 中使用属性一样。

作为替代方案,现在有一个名为react-html-parser的库您可以在此 URL 的 NPM 注册表中检查并安装:https : //www.npmjs.com/package/react-html-parser该软件包今天的每周下载统计数据为23,696看起来很受欢迎的库使用。即使它看起来更方便使用,我自己在真正使用它之前仍然需要更多的阅读和进一步的考虑。

从 NPM 页面复制的代码片段:

import React from 'react';
import ReactHtmlParser, { processNodes, convertNodeToElement, htmlparser2 } from 'react-html-parser';

class HtmlComponent extends React.Component {
  render() {
    const html = '<div>Example HTML string</div>';
    return <div>{ ReactHtmlParser(html) }</div>;
  }
}
dangerouslySetInnerHTML我认为选项好得多
2021-06-07 01:44:43
它的作用与dangerouslySetInnerHTML. 没用
2021-06-16 01:44:43
这一年是 2020 年。要查看的活跃 Github 存储库是:https : //github.com/remarkablemark/html-react-parser
2021-06-16 01:44:43

我最近遇到了这个答案,这对我来说很划算。您不需要提供字符串。返回一组 JSX 元素即可解决问题。

我们可以将 JSX 元素存储在 JavaScript 数组中。

let arrUsers = [<li>Steve</li>,<li>Bob</li>,<li>Michael</li>];

并在你的 HTML (JSX) 中绑定它,

<ul>{arrUsers}</ul>

就这么简单。

如果内容是动态的,这有效,如果标签名称 itslef 是动态的怎么办?
2021-05-30 01:44:43

如果你考虑字符串

<div>Hello World</div>

如果我们非常严格,这实际上是有效的 JSX。问题是如何将这个 JSX 字符串编译成 React 代码。

最简单和推荐的方法是下载一些像 Babel 这样的库并使用它来转换代码。Babel 可以像repl一样在浏览器中运行

也可以将 JSX 转换为其他格式,但在这种情况下,您必须找到一个编译器或自己创建一个。

自己创建 JSX => React 转换的步骤是:

  1. 将代码字符串转换为 AST 表示
  2. 解析 AST 并将代码输出回字符串

所以你需要某种 AST 解析器,比如支持 JSX 的espree,然后你可以创建一个代码来遍历AST 树并输出一些东西,比如 React 代码。

JSX 数据的 AST 树由普通的 JavaScript AST 和 JSX 节点组成。解析器应该遍历树并将 JSX 节点转换为正常的 JavaScript 代码。

如果您编译为 React 并遇到带有标记“div”的 JSX 节点,您应该将其编译为React.createElement("div",...调用,在该 AST 节点下找到的属性和子节点作为该调用的参数插入。

我创建了一个小的 AST Walker,它可以处理 AST 树ASTWalker,它可以用来将 AST 树转换成某种输出格式,比如 React 或 DOM。

如何使用它的在线示例在这里:

http://codepen.io/teroktolonen/pen/KzWVqx?editors=1010

主要代码如下所示:

    // here is the JSX string to parse
    var codeStr = "<div>Hello world</div>";
    var walker = ASTWalker({
        defaultNamespace: "react",
    });
    // compile AST representation out of it.
    var rawAST = espree.parse(codeStr, {
          ecmaVersion: 6,
          sourceType: "script",
          // specify additional language features
          ecmaFeatures: {
            // enable JSX parsing
            jsx: true
          } 
        });

   // then you can walk the walk to create the code
   walker.startWalk( rawAST, {} );
   var code = walker.getCode();  
   console.log(code); 
   document.getElementById("sourceCode").innerHTML = code;

免责声明:该库不打算编译成 React。它主要用于defaultNamespace: "DOM",将其编译为纯 JavaScript + DOM 表示。尝试任何比简单标签更复杂的东西都可能导致错误。

重要的是要注意 React 不仅是 JSX 可能的输出格式。

您在这里拥有的<div>Hello World</div>不是字符串。但是你说它是 JSX 是对的。This:"<div>Hello World</div>"是一个字符串,而不是 JSX。没有“JSX 字符串”这样的东西。小心你的答案,因为它可能会令人困惑。
2021-05-23 01:44:43

下面是如何做到这一点,而不使用危险的SetInnerHTML。

import React from "react";

let getNodes = str =>
  new DOMParser().parseFromString(str, "text/html").body.childNodes;
let createJSX = nodeArray => {
  const className = nodeArray[0].className;
  return nodeArray.map(node => {
    let attributeObj = {};
    const {
      attributes,
      localName,
      childNodes,
      nodeValue
    } = node;
    if (attributes) {
      Array.from(attributes).forEach(attribute => {
        if (attribute.name === "style") {
          let styleAttributes = attribute.nodeValue.split(";");
          let styleObj = {};
          styleAttributes.forEach(attribute => {
            let [key, value] = attribute.split(":");
            styleObj[key] = value;
          });
          attributeObj[attribute.name] = styleObj;
        } else {
          attributeObj[attribute.name] = attribute.nodeValue;
        }
      });
    }
    return localName ?
      React.createElement(
        localName,
        attributeObj,
        childNodes && Array.isArray(Array.from(childNodes)) ?
        createJSX(Array.from(childNodes)) :
        []
      ) :
      nodeValue;
  });
};

export const StringToJSX = props => {
  return createJSX(Array.from(getNodes(props.domString)));
};

StringToJSX按以下格式导入并作为props传递字符串。

<StringToJSX domString={domString}/>

PS:我可能错过了一些边缘情况,比如属性。

不幸的是,这不适用于服务器端渲染,因为它DOMParser是特定于浏览器的
2021-06-14 01:44:43
不知道为什么这没有最多的赞成票..太棒了!我用它来制作 svg,虽然我不得不改变很多,但仍然帮助了很多!危险的SetInnerHtml 不能很好地与SVG 一起工作,这很好用。
2021-06-18 01:44:43