aknuds1/html-to-react

Feature Request/Does this exists? Replace element with another

Closed this issue · 9 comments

I have some html as a string e.g.

<div>
  Here is my code with a <a href="myLink">link</a>
</div>

I would like to replace the a tag with my own custom <Link /> component is this possible?

I am currently cheating by doing: (is there a better way)

    const content = this.props.content
      .replace(/<a/g, '<span data-link="link"')
      .replace(/<\/a/g, '</span')
        replaceChildren: true,
        shouldProcessNode: node => {
          return node.attribs && node.attribs['data-link'] === 'link'
        },
        processNode: (node, children) =>  {
          delete node.attribs.href;
          return <Link>{children}</Link>
        }
TimNZ commented
shouldProcessNode: node => {
          return node.name == 'a'
        },

My Goal is to take replace a node with another node (Custom react component)

<div>
  Here is my code with a <a href="myLink">link</a>
</div>

and have it output

<div>
  Here is my code with a <Link href="myLink">link</Link>
</div>

if I return node.name == 'a' then the processNode will only alter the content inside the tag e.g. <a>CONTENT HERE IS CHANGED</a>

TimNZ commented
replaceChildren: false
TimNZ commented

I was tripped up as well.
The README needs a bit of tweaking, otherwise this package is pretty solid.

I guess this issue is solved :) I'm not sure how the README could be improved to be honest. I didn't write this functionality, or document it, originally, but I can see that the README contains instructions on custom processing and the use of replaceChildren.

TimNZ commented

@aknuds1 fair enough.
I only quickly skimmed the readme and copied the custom processing snippet.
On re-read, it's clear replaceChildren defaults to false and doesn't need to be specified.

@davelaker did you solve it in the end? Facing the same problem.

This is my code:

  var processingInstructions = [
    {
      shouldProcessNode: function(node) {
        // Custom <a> processing
        return node.parent && node.parent.name && node.parent.name === 'a';
      },
      // eslint-disable-next-line react/display-name
      processNode: function(_, children) {
        return <Anchor>{children}</Anchor>;
      }
    },
    {
      // Anything else
      shouldProcessNode: function() {
        return true;
      },
      processNode: function() {
        return processNodeDefinitions.processDefaultNode;
      }
    }
  ];

  var htmlToReactParser = new HtmlToReactParser();
  var reactComponent = htmlToReactParser.parseWithInstructions(
    htmlString,
    isValidNode,
    processingInstructions
  );

I don't think replaceChildren replaces the actual node, it just replaces the children of the node