如何将字符串转换为jsx?

jha*_*amm 27 reactjs react-jsx

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

var jsxString = document.getElementById('textarea').value;
Run Code Online (Sandbox Code Playgroud)

我将使用什么过程在客户端上转换它?可能吗?

小智 26

您可以考虑使用JSX属性 dangerouslySetInnerHTML

以下示例用法:

class YourComponent{

render() {
   someHtml = '<div><strong>blablabla<strong><p>another blbla</p/></div>'

   return(
       <div className="Container" dangerouslySetInnerHTML={{__html: 
        someHtml}}></div>
    )
  }
}
Run Code Online (Sandbox Code Playgroud)

我知道你迟到了:)但希望它可以帮助别人

  • 这在渲染 **React Components** 的情况下不起作用`不要看到你的帖子 &lt;Link to=\"/add-professor\"&gt;添加你的帖子&lt;/Link&gt;` 在这种情况下`&lt;Link&gt;`没有得到应有的渲染 (8认同)
  • `dangerouslySetInnerHTML` 不允许在标签内使用驼峰式名称,它会将它们转换为小写。这是因为它适用于 html 标签。 (3认同)
  • **警告**:`dangerouslySetInnerHTML` 容易受到 XSS 攻击。 (2认同)

Bal*_*i M 11

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

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

let arrUsers = [<li>Steve</li>,<li>Bob</li>,<li>Michael</li>];
Run Code Online (Sandbox Code Playgroud)

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

<ul>{arrUsers}</ul>
Run Code Online (Sandbox Code Playgroud)

就这么简单。


Ter*_*nen 7

如果考虑字符串

<div>Hello World</div>
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

因此,您需要诸如支持JSX的espree之类的AST解析器,然后您可以创建一个代码,该代码遍历 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;
Run Code Online (Sandbox Code Playgroud)

免责声明:该库不适用于编译到React中。它通常用于defaultNamespace: "DOM",将其编译为纯JavaScript + DOM表示形式。尝试比简单标签更复杂的事情都可能导致错误。

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


小智 7

以下是不使用危险的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)));
};
Run Code Online (Sandbox Code Playgroud)

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

<StringToJSX domString={domString}/>
Run Code Online (Sandbox Code Playgroud)

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

  • 不知道为什么这没有得到最多的支持..太棒了!我用它来制作 svg,虽然我不得不改变很多,但仍然帮助了很多!angeredlySetInnerHtml 与 SVG 的配合不太好,但这个效果很好。 (2认同)

Bay*_*ayu 6

就个人而言,我喜欢这样做,就像前面的建议(建议dangerouslySetInnerHTML在JSX中使用property)一样。

只是作为一种替代,如今有一个名为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>;
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 今年是 2020 年。要查看的活跃 Github 存储库是:[https://github.com/remarkablemark/html-react-parser](https://github.com/remarkablemark/html-react-parser) (4认同)
  • 它与“dangerouslySetInnerHTML”执行相同的操作。没用 (2认同)

dan*_*lie 5

我一直在使用html-to-react取得一些成功(尽管自关闭标签会引起问题,但是在pull request中已解决了问题……)将标记字符串解析为DOM一样的对象,然后将React元素解析。它不漂亮,如果可以避免,请这样做。但这完成了工作。

github上的html-to-react:https : //github.com/mikenikles/html-to-react


Abr*_*ham 5

使用React-JSX-Parser

您可以使用专门用于此目的的 React-JSX-Parser 库。

npm install react-jsx-parser

是回购协议


Dmi*_*rov -9

你需要使用带有预设react的babel

npm install --save-dev babel-cli babel-preset-react
Run Code Online (Sandbox Code Playgroud)

将以下行添加到您的.babelrc文件中:

{
  "presets": ["react"]
}
Run Code Online (Sandbox Code Playgroud)

然后运行

./node_modules/.bin/babel script.js --out-file script-compiled.js
Run Code Online (Sandbox Code Playgroud)

您可以在这里找到更多信息