简体   繁体   English

React markdown - 如何使用 react-markdown 或 dangerouslySetInnerHTML 获取第 n 个元素和 append 另一个元素?

[英]React markdown - how to get nth-element and append another element using react-markdown or dangerouslySetInnerHTML?

I'm looking to append a button after the 2nd paragraph in a react html markdown implementation.我正在寻找 append 在反应 html markdown 实现的第二段之后的按钮。 I am currently using react-markdown to compile my html code.我目前正在使用 react-markdown 来编译我的 html 代码。 A few things I am trying to do here:我在这里尝试做的几件事:

  1. Get nth element of the react markdown html (ex: p:2nd-child)获取反应 markdown html 的第 n 个元素(例如:p:2nd-child)
  2. Create new element (ex: document.createElement('button'))创建新元素(例如:document.createElement('button'))
  3. Append after the (p:2nd-child) element the new button Append (p:2nd-child) 元素后的新按钮

Should I use ref to achieve this or is it as simple as appending with plain JavaScript??我应该使用 ref 来实现这一点,还是像附加普通的 JavaScript 一样简单? Open to other suggestions if there is a better solution.如果有更好的解决方案,请接受其他建议。

index.jsx索引.jsx

import React, { useEffect } = 'react'
import ReactMarkdown from 'react-markdown'

const Markdown = (props) => {
  // props.contentHTML seems to be typeof string (with no html tags. 
  //ex: 'hello world' vs '<p>hello world</p>') but converts to appropriate element tags
  const reactHTML = <ReactMarkdown children={props.contentHTML} />

  useEffect(() => {
    // how do i get 2nd element of that reactHTML p tag??
    let secondPElement = ?? reactHTML.querySelector..... ??

    // create element for my button
    let button = document.createElement('button');
    button.id = 'btn-1';
  
    // error here: appendChild does not exist on type 'Element'
    reactHTML.appendChild(button)
  })

  return (
    {reactHTML}
  )

} 

export default Markdown

Unfortunately, I don't think there's a way to achieve this without doing something a little unorthodox (read: hacky).不幸的是,如果不做一些不正统的事情(阅读:hacky),我认为没有办法实现这一点。

TLDR: Here's a sandbox with what I think is a viable solution for you. TLDR:这是一个沙盒,我认为对您来说是一个可行的解决方案。

Continuing on, there are a couple of problems preventing your code from working.继续,有几个问题阻止您的代码工作。

When you define reactHTML you're not actually defining HTML but rather a react Element Object (because that's what JSX compiles it into).当您定义reactHTML时,您实际上并没有定义HTML而是一个 react Element Object (因为这是 JSX 编译成的)。

This means that you won't be able to use DOM selectors on it (eg querySelector and appendChild ) and that is why you get the error appendChild does not exist on type 'Element' .这意味着您将无法在其上使用 DOM 选择器(例如querySelectorappendChild ),这就是您收到错误appendChild does not exist on type 'Element'原因。 This makes sense because the react Element object does not have such a method.这是有道理的,因为 react Element object没有这样的方法。

The "solution" then, is to render your markdown content as you normally would, and only after being rendered go in and access the elements that you want.然后,“解决方案”是像往常一样渲染您的 markdown 内容,并且仅在渲染 go 并访问您想要的元素之后。 This can be easily achieved with the useEffect hook very similar to what you're already doing:这可以通过与您已经在做的非常相似的useEffect挂钩轻松实现:

const Markdown = (props) => {
  const markdown = `
  This is rendered as a '<p>' element

  So is this one!

  Me too!
  `;

  useEffect(() => {
    // Get all of the <p> elements
    const pElements = document.getElementsByTagName("p");

    // Create a button
    const button = document.createElement("button");
    button.id = "btn-1";
    button.innerHTML = "I'm a button!";

    const refChild = pElements[1];
    // Insert the button before the next sibling of the second <p> tag
    refChild && refChild.parentNode.insertBefore(button, refChild.nextSibling);
  }, []);

  return <ReactMarkdown children={markdown} />;
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM