【问题标题】:Extract raw HTML in react-native-render-html custom renderer在 react-native-render-html 自定义渲染器中提取原始 HTML
【发布时间】:2021-06-12 00:55:38
【问题描述】:

我正在使用 react-native-render-html 来渲染 html。 renderers 方法允许我提供自定义函数来呈现特定标签。但是我想用我的自定义组件替换子组件,使用源代码中的原始内部 HTML。

考虑一下。我将以下 html sn-p 提供给<HTML /> 组件:

<a> <b> <c meta="xyz"> Some text </c> <b> </a>

我有一个自定义渲染器,它返回一个组件,该组件接受一个 html 字符串并用它做一些魔术:

const renderers = {
  c: () => (
    <Custom html={/** how do I get "<c meta="xyz"> Some text </c>"? */} />
  )
}

【问题讨论】:

    标签: react-native-render-html


    【解决方案1】:

    API 最初不是为处理这类用例而设计的,但对于 5.0.0 版本来说,它非常简单!

    版本 6.x

    import * as React from 'react';
    import HTML, {domNodeToHTMLString} from 'react-native-render-html';
    
    function CustomRenderer({ tnode, style, key }) {
      const html = React.useMemo(() => domNodeToHTMLString(tnode.domNode), [tnode]);
      return <Custom key={key} html={html} style={style} />;
    }
    

    版本 5.x

    从第 5 版开始,借助新的 domNodeToHTMLString util 非常容易,请参见下面的 sn-p:

    import * as React from 'react';
    import HTML, {domNodeToHTMLString} from 'react-native-render-html';
    
    function customRenderer(htmlAttribs, children, inlineStyle, passProps) {
      const html = domNodeToHTMLString(passProps.domNode);
      return <Custom key={passProp.key} html={html} />;
    }
    

    版本 4.x 及以下

    要使用此 hack,您需要将“stringify-entities”添加到依赖项列表中。这个 hack 的基本作用是使用 alterNode 钩子向 DOM 节点添加一个非常规的 __rawHtml 属性。该属性随后将传递给渲染器函数。

    import * as React from 'react';
    import HTML from 'react-native-render-html';
    import strigifyEntities from 'stringify-entities';
    import Custom from './Custom';
    
    function renderOpeningTag(tag, attributes) {
      const strAttributes = [];
      Object.keys(attributes).forEach((key) => {
        strAttributes.push(`${key}="${strigifyEntities(`${attributes[key]}`)}"`);
      });
      return `<${tag}${strAttributes.length ? ' ' : ''}${strAttributes.join(' ')}>`;
    }
    
    function nodeToRawHTML(root) {
      let html = '';
      if (root.type === 'tag') {
        const strChildren = root.children.reduce((prev, curr) => {
          return `${prev}${nodeToRawHTML(curr)}`;
        }, '');
        html = `${renderOpeningTag(root.name, root.attribs)}${strChildren}</${
          root.name
        }>`;
      } else if (root.type === 'text') {
        const text = strigifyEntities(root.data);
        html = text;
      }
      return html;
    }
    
    function alterNode(node) {
      if (node.type === 'tag' && node.name === 'c') {
        node.attribs.__rawHtml = nodeToRawHTML(node);
      }
    }
    
    const renderers = {
      c: ({__rawHtml}, children, convertedCSSStyles, passProp) => {
        return <Custom key={passProp.key} html={__rawHtml} />
      },
    };
    
    export default function App() {
      return (
        <HTML
          renderers={renderers}
          alterNode={alterNode}
          html={'<a> <b> <c meta="xyz"> Some text </c> <b> </a>'}
        />
      );
    }
    

    【讨论】:

    • 哦。我的。上帝。脑洞大开,伙计!你是一个真正的救生员!折腾了4天,终于被你救了!
    猜你喜欢
    • 1970-01-01
    • 2015-06-02
    • 2012-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多