I'm new to React and having some difficulty trying to add a new child component to a component that has already been rendered.
I have an App component which initially contains a Main component (main menu).
I also have Popover components which I want to appear on top of Main when they are children of <App> (and hence siblings of <Main>).
These Popover components vary in number. Each <Popover> can contain buttons which launch another <Popover> over the top again. So the structure would be like
<App>
<Main></Main>
<Popover></Popover>
<Popover></Popover>
...
</App>
However, when the page first loads there are no Popover components open, and the<App> is rendered without any. Here is a stripped-down version of my code:
class App extends React.Component{
constructor(props){ super(props) }
render(){
return (
<div>{this.props.children}</div>
)
}
}
class Main extends React.Component{
constructor(props){ super(props) }
render(){
return (
//main menu stuff here
)
}
}
ReactDOM.render(<App><Main /></App>, root);
How can I add new <Popover>s to my <App> when the user clicks something? Before React I would simply do App.appendChild(Popover) kind of thing, but I'm quite lost here.
I should add that the elements the user will click to trigger an initial <Popover> are not contained within <Main>; they are outside of the <App>, as I am trying to slowly transition my existing page to using React. I think this could be part of my problem.
So basically in React, you have multiple ways of doing this, but to be more reliable you need to have data that represents the dynamic components you will render in your DOM. And to do this you need to create a state and a function that can add new information to your state. Then simply by sharing this function with your other components, you can trigger it from wherever you want, and this will update your state which will increase the amount of dynamic components you will render.
Take a look at this example
import { useState } from "react";
export default function App() {
const [popups, setPopups] = useState([]);
const addNewPopup = () => {
setPopups([...popups, { title: "I am a popup" }]);
};
return (
<div className="App">
<ChildComponent onClick={addNewPopup} />
{popups.map((p) => {
return <Popup title={p.title} />;
})}
</div>
);
}
function ChildComponent({ onClick }) {
return (
<div>
<p>I am a child component</p>
<button onClick={onClick}>Add new element</button>
</div>
);
}
function Popup({ title }) {
return <div>I am a popup with title = {title}</div>;
}