Search code examples
reactjsdynamicappendchild

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

  • function App() {
      // declare array of boxes
      const [boxes, setBoxes] = useState([]);
    
      const handleClick = ({ pageX, pageY }) => {
        // on every click push a new coordinate to the boxes array
        setBoxes((boxes) => [...boxes, { x: pageX, y: pageY }]);
      };
    
      return (
        <div className="app" onClick={handleClick}>
          // display boxes
          {boxes.map((box) => (
            // map coordinates to left and top
            <div className="box" style={{ left: box.x, top: box.y }}></div>
          ))}
        </div>
      );
    }
    

    Styles, mostly copied from the codepen

    .app {
      width: 100%;
      height: 100vh;
    }
    
    .box {
      position: absolute;
      width: 50px;
      height: 50px;
      background: red;
      transform: translate(-50%, -50%);
    }
    

    sandbox