简体   繁体   English

使用带有 React 组件的 insertAdjacentHTML

[英]using insertAdjacentHTML with a React Component

So I'm trying to recreate the Github contribution grid using React.所以我正在尝试使用 React 重新创建 Github 贡献网格。

I'm trying to use insertAdjacentHTML to populate the grid container with a bunch of divs that I can then style.我正在尝试使用 insertAdjacentHTML 用一堆 div 填充网格容器,然后我可以设置它们的样式。

However, React is throwing me an error "TypeError: Cannot read property 'insertAdjacentHTML' of null"但是,React 给我一个错误“TypeError:无法读取属性 'insertAdjacentHTML' of null”

Here is my simple code:这是我的简单代码:

export default function NewHabit() {
  const gridContainer = document.querySelector('.grid-container');

  for (let i = 0; i < 365; i++) {
    gridContainer.insertAdjacentHTML('beforeend', `<div id="box></div>`);
  }

  return (
    <div>
      <div className="grid-container"></div>
    </div>
  );
}

the component is not rendered yet when NewHabit starts to execute.当 NewHabit 开始执行时,组件尚未呈现。
you have to put it after componentDidMount or useEffect(() => {}, []) , they execute after the component mounts and has been added to the DOM.您必须将它放在componentDidMountuseEffect(() => {}, [])之后,它们在组件安装并添加到 DOM 后执行。

besides, it's not safe to do this using insertAdjacentHTML/Elmenent .此外,使用insertAdjacentHTML/Elmenent这样做是不安全的。 react has a virtual dom that does not keep this type of change in it. react 有一个虚拟 dom,它不会保留这种类型的变化。 after a rerender, it might render what it had in the virtual dom.在重新渲染之后,它可能会渲染它在虚拟 dom 中的内容。 for example, an empty grid.例如,一个空网格。 it's better to add your boxes in react way.最好以反应方式添加你的盒子。

Solved it by just doing it the React way:仅通过 React 方式解决它:

export default function NewHabit() {
  let grid = [];
  for (let i = 0; i < 365; i++) {
    grid.push(<div className="box"></div>);
  }

  return (
    <div>
      <div className="grid-container">{grid}</div>
    </div>
  );
}

First of all, read carefully the Refs and the DOM part of the React documentation.首先,仔细阅读 React 文档的Refs 和 DOM部分。 The important thing you should learn is the fact that React is working using virtual DOM, so you don't have a direct access to the browser's DOM.您应该了解的重要一点是 React 使用虚拟 DOM 工作,因此您无法直接访问浏览器的 DOM。

Second, I really discourage you from the direct DOM manipulation.其次,我真的不鼓励你直接操作 DOM。 React offers you a number of options to render html dynamically (actually, it renders dynamically all the time). React 为您提供了许多动态呈现 html 的选项(实际上,它一直在动态呈现)。 For example, instead of inserting html you may use lists and keys :例如,您可以使用列表和键来代替插入 html :

export default function NewHabit() {
  let gridElements = []
  for (let i = 0; i < 365; i++) {
    gridElements.push(<div id="box" key={i}></div>)
  }

  return (
    <div>
      <div className="grid-container">{gridElements}</div>
    </div>
  );
}

But if you really want the direct DOM access, just use ref:但如果你真的想要直接 DOM 访问,只需使用 ref:

import {useRef} from 'react'

export default function NewHabit() {
  const containerRef= useRef(null);

  if (containerRef.current) {
    for (let i = 0; i < 365; i++) {
      containerRef.current.insertAdjacentHTML('beforeend', `<div id="box></div>`);
    }
  }

  return (
    <div>
      <div className="grid-container" ref={containerRef}></div>
    </div>
  );
}

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

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