我将如何获取一个字符串,并将其转换为jsx
?例如,如果我从 a 中引入一个字符串textarea
,我如何将其转换为一个React
元素;
var jsxString = document.getElementById('textarea').value;
我将使用什么过程在客户端转换它?是否可以?
我将如何获取一个字符串,并将其转换为jsx
?例如,如果我从 a 中引入一个字符串textarea
,我如何将其转换为一个React
元素;
var jsxString = document.getElementById('textarea').value;
我将使用什么过程在客户端转换它?是否可以?
您可以考虑使用 React 属性dangerouslySetInnerHTML
:
class YourComponent{
render() {
someHtml = '<div><strong>blablabla<strong><p>another blbla</p/></div>'
return (
<div className="Container" dangerouslySetInnerHTML={{__html: someHtml}}></div>
)
}
}
就个人而言,我喜欢这样做,就像在之前的答案中建议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>;
}
}
我最近遇到了这个答案,这对我来说很划算。您不需要提供字符串。返回一组 JSX 元素即可解决问题。
我们可以将 JSX 元素存储在 JavaScript 数组中。
let arrUsers = [<li>Steve</li>,<li>Bob</li>,<li>Michael</li>];
并在你的 HTML (JSX) 中绑定它,
<ul>{arrUsers}</ul>
就这么简单。
如果你考虑字符串
<div>Hello World</div>
如果我们非常严格,这实际上是有效的 JSX。问题是如何将这个 JSX 字符串编译成 React 代码。
最简单和推荐的方法是下载一些像 Babel 这样的库并使用它来转换代码。Babel 可以像repl一样在浏览器中运行。
也可以将 JSX 转换为其他格式,但在这种情况下,您必须找到一个编译器或自己创建一个。
自己创建 JSX => React 转换的步骤是:
所以你需要某种 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 可能的输出格式。
下面是如何做到这一点,而不使用危险的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:我可能错过了一些边缘情况,比如属性。