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??
CodePudding user response:
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>
CodePudding user response:
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
).