javascript - React markdown - 如何使用 react-markdown 或危险的 SetInnerHTML 获取第 n 个元素并附加另一个元素?
问题描述
我希望在 react html markdown 实现的第二段之后附加一个按钮。我目前正在使用 react-markdown 来编译我的 html 代码。我在这里尝试做的几件事:
- 获取 react markdown html 的第 n 个元素(例如:p:2nd-child)
- 创建新元素(例如:document.createElement('button'))
- 在 (p:2nd-child) 元素之后附加新按钮
我应该使用 ref 来实现这一点,还是像附加纯 JavaScript 一样简单?如果有更好的解决方案,请接受其他建议。
索引.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
解决方案
不幸的是,如果不做一些非正统的事情(阅读:hacky),我认为没有办法实现这一点。
TLDR:这是一个沙盒,我认为对您来说是一个可行的解决方案。
继续,有几个问题阻止您的代码工作。
当您定义时,reactHTML
您实际上并不是在定义HTML,而是在定义一个 reactElement
对象(因为 JSX 将它编译成它)。
这意味着您将无法在其上使用 DOM 选择器(例如querySelector
and appendChild
),这就是您收到错误消息的原因appendChild does not exist on type 'Element'
。这是有道理的,因为 reactElement
对象没有这样的方法。
那么,“解决方案”就是像往常一样呈现您的降价内容,并且只有在呈现后才能进入并访问您想要的元素。这可以通过与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} />;
};
推荐阅读
- javascript - 我可以为同一个 es lint 规则强制执行多个级别吗?例如:不同路径的错误和警告
- compression - 使用 DEFLATE 压缩文本文件时,需要多少数据才能减小大小?
- c - 在给定的 BST 中查找最大子树,使其没有重复项
- css - Bootstrap 列宽调整
- python - 递归特征消除后无法进行预测
- nsregularexpression - 正则表达式 - 通过特定模板查找字母
- java - 将 ejb-jar 描述符应用于抽象类
- typescript - 在 TypeScript 中,如何使用位于另一个文件中的类
- ios - 如何通过 Web 服务将数据从我的应用程序插入到 BD?
- hyperledger-fabric - 如何配置网络以启用发现服务