在同构React应用中渲染HTML字符串

在同构React应用中渲染HTML字符串,第1张

在同构React应用中渲染HTML字符串

可以通过将html字符串解析并将生成的节点转换为React元素,将经过处理的HTML转换为可在服务器和客户端上运行的React组件。

const React = require('react');const ReactDOMServer = require('react-dom/server');const str = `<div>divContent<p> para 1</p><p> para 2</p><gallery image-ids="" /><player video-id="" /><p> para 3</p><gallery image-ids="[1, 3]"/></div>`;var parse = require('xml-parser');const Gallery = () => React.createElement('div', null, 'Gallery comp');const Player = () => React.createElement('div', null, 'Player comp');const componentMap = {  gallery: Gallery,  player: Player};const traverse = (cur, props) => {  return React.createElement(    componentMap[cur.name] || cur.name,    props,    cur.children.length === 0 ? cur.content: Array.prototype.map.call(cur.children, (c, i) => traverse(c, { key: i }))  );};const domTree = parse(str).root;const App = traverse(   domTree);console.log(  ReactDOMServer.renderToString(    App  ));

但是请注意,您并不是真正需要的JSX / TSX,而是React渲染器的React
Nodes树(在这种情况下为ReactDOM)。JSX只是语法糖,除非您想在代码库中维护React输出,否则不需要来回转换它。

请原谅过度简化的html解析。它仅用于说明目的。您可能想使用符合规范的库来解析输入的html或适合您的用例的内容。

确保客户端捆绑软件获得完全相同的

App
组件,否则您可能会因为React的客户端脚本重新创建DOM树而失去服务器渲染的所有好处。

您也可以通过上述方法利用React 16的流式传输。

解决道具问题

道具将从树中作为属性提供给您,并且可以作为道具传递(在仔细考虑课程用例的情况下)。

const React = require('react');const ReactDOMServer = require('react-dom/server');const str = `<div>divContent<p> para 1</p><p> para 2</p><gallery image-ids="" /><player video-id="" /><p> para 3</p><gallery image-ids="[1, 3]"/></div>`;var parse = require('xml-parser');const Gallery = props => React.createElement('div', null, `Gallery comp: Props ${JSON.stringify(props)}`);const Player = () => React.createElement('div', null, 'Player comp');const componentMap = {  gallery: Gallery,  player: Player};const attrsToProps = attributes => {  return Object.keys(attributes).reduce((acc, k) => {    let val;    try {      val = JSON.parse(attributes[k])    } catch(e) {      val = null;    }    return Object.assign(      {},      acc,      { [ k.replace(/-/g, '') ]: val }    );  }, {});};const traverse = (cur, props) => {  const propsFromAttrs = attrsToProps(cur.attributes);  const childrenNodes = Array.prototype.map.call(cur.children, (c, i) => {    return traverse(      c,      Object.assign(        {},        {          key: i        }      )    );  });  return React.createElement(    componentMap[cur.name] || cur.name,      Object.assign(        {},        props,        propsFromAttrs      ),    cur.children.length === 0 ? cur.content: childrenNodes  );};const domTree = parse(str).root;const App = traverse(  domTree);console.log(  ReactDOMServer.renderToString(    App  ));

但是请谨慎使用自定义属性-
您可能要遵循此rfc。如果可能,请坚持使用camelCase。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5049728.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-15
下一篇 2022-11-15

发表评论

登录后才能评论

评论列表(0条)

保存