How do I dynamically add a div where mouse was clicked in React?

I’m new to react and wonder how to do weird code stuff. I have a div component that I need to add child divs to depending on where I clicked on the div. I could do this easily in vanilla JS – here is a code sandbox of JS of what I want to do : https://codepen.io/Webasics/pen/YXXyEO

here is what I have in react so far (this is inside my App component):

const imgAdder = (e) => {
  console.log(e.pageX, e.pageY)
}

<main onClick={imgAdder} </main>
$(document).ready(function() {
  $(this).click(function(e) {
    var x = e.pageX;
    var y = e.pageY;
    $('<div/>').css({
      'top': y,
      'left': x
    }).appendTo('body');
  });
});
div {
  background-color: red;
  width: 50px;
  height: 50px;
  position: absolute;
  transform: translate(-50%, -50%);
  /* optional */
  border: 1px solid black;
  /* optional */
}

h2 {
  z-index: 10;
  /* optional */
  /* This always keeps the title on top*/
  position: absolute;
}

body {
  background-color: #E1E7E8;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h2>Click anywhere</h2>

Any directions would be lovely ! thank you.

>Solution :

Weird, but I like it!

https://codesandbox.io/s/elated-meadow-zuerrg?file=/src/App.js

I would simply use useEffect to register a click handler on the document and on click, add elements to a state array.

Finally, render those elements onto the page.

import { useEffect, useState } from "react";
import "./styles.css";

export default function App() {
  const elements = useDynamicElements();

  return (
    <>
      <h2>Click anywhere</h2>
      {elements}
    </>
  );
}

const useDynamicElements = () => {
  const [state, setState] = useState([]);

  useEffect(() => {
    const handler = (event) => {
      setState((previous) => [
        ...previous,
        <div style={{ top: event.pageY, left: event.pageX }} />
      ]);
    };
    document.addEventListener("click", handler);
    return () => document.removeEventListener("click", handler);
  });

  return state;
};

Leave a Reply