'how to add an element by clicking action in React?

I'm creating a simple logic here. If one click an element from left-side box, the element will be deleted and added to right-box. So, I create this functions

function deleteElement(e: any){
const clickedElement = e.target
  clickedElement.remove()
  const addedElement = <div onClick={addedItem}><input type="checkbox" className="fruits" value="apple" id="apple" /><label htmlFor="apple" className="fruit-name">Apple</label></div>
  const rightBox = document.getElementById("rightBox")
  rightBox?.appendChild(addedElement)
  console.log("The Element Has Been Added To Your Cart.");
}

but react/ts says

Argument of type 'Element' is not assignable to parameter of type 'Node'. Type 'ReactElement<any, any>' is missing the following properties from type 'Node': baseURI, childNodes, firstChild, isConnected, and 46 more

So, type "Element" is not assignable to parameter of type 'node' ← this means appendChild is node system, right? then How should I add any element in right-box??



Solution 1:[1]

You should be storing the children of the box as a state:

const [boxChildren, setBoxChildren] = useState([]);

return (
    <div>
        {boxChildren}
    </div>
);

Then to add/delete on click (element is something like <div></div>):

setBoxChildren([...boxChildren, element]); // .push

setBoxChildren([element, ...boxChildren]); // .unshift

setBoxChildren(boxChildren.slice(0, -1)); // .pop

setBoxChildren(boxChildren.slice(1)); // .shift

So for example, click the button to add elements:

function App() {
  const [boxChildren, setBoxChildren] = React.useState([]);

  return (
      <div>
          <button onClick={
              () => setBoxChildren([...boxChildren, <div>hello</div>])
          }>add</button>
          {boxChildren}
      </div>
  );
}

ReactDOM.render(<App />, document.body);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>

Solution 2:[2]

I strongly suggest to not inject html in react in this way.

You should find a more react-compliant way like create a state variable and conditional render html:

import React, { useState } from 'react';

function myComponent = () => {
   const [position, setPosition] = useState("left");

   const addedItem = (newPos) => {
       setPosition(newPos);
   } 
  
   return (
     <div>
        <LeftBox>{position === "left" && <div onClick={() => addedItem("right")}><input type="checkbox" className="fruits" value="apple" id="apple" /><label htmlFor="apple" className="fruit-name">Apple</label></div>}</LeftBox>
        <RightBox>{position === "right" && <div onClick={() => addedItem("left")}><input type="checkbox" className="fruits" value="apple" id="apple" /><label htmlFor="apple" className="fruit-name">Apple</label></div>}</RightBox>
     </div>
   );
}

export default myComponent;

In this example, every time you click div, checkbox will be rendered from an hypotetical component rendered on left side (I called it LeftBox) to another hypotetical component rendered on right side (I called it RightBox).

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 hittingonme
Solution 2 Giovanni Esposito