'How to append different react components to a list on a click of a button?

I have two kinds of components, I want them to appear in the screen on the click of a button, but it is not like show and hide components, it is more like generate theme many times. like if I click the button, I can add more and more, so if i click on the first button it generates component 1 and when I click on the second button it appends the second component to the list and etc.

I have no idea how to achieve this, I thought of storing the components in a state and do a map loop, but i not sure if this possible (storing components in state) and if it's a good practice.



Solution 1:[1]

I think I have had a similar situation while making a math solving website where I wanted to show the solution (JSX Element) when the user clicks on "solve" button. I don't know if this is the best practice but I just created a SolutionObject with the following typescript interface:

interface SolutionObject {
  isSolved: boolean;
  solutionElement: JSX.Element;
}

I then initialised the solution object using the useState() hook:

const [Solution, solved] = useState<SolutionObject>();

Then I used it in my React component like this

<div className="solution">
    {Solution?.solutionElement}
</div>
{Solution?.isSolved ? <button onClick={closeBtn}>Close</button> : null} 

To update the solution, I just updated the solution object with the JSX in solutionElement property in a solve function with the correct JSX for step-by-step solution. Here is an example:

solved({
      isSolved: true,
      solutionElement:
        // prettier-ignore
        <div className="card">
          <h2>Using Distance Formula</h2>
          <p>
            <Latex>{`$Distance\\ (D) = \\sqrt{(x_{2}-x_{1})^2 + (y_{2}-y_{1})^2}$`}</Latex>
            <br /><br />
            <Latex>{`$D = \\sqrt{(${X2}-${X1})^2 + (${Y2}-${Y1})^2}$`}</Latex>
            <br /><br />
            <Latex>{`$D = \\sqrt{(${X2 - X1})^2 + (${Y2 - Y1})^2}$`}</Latex>
            <br /><br />
            <Latex>{`$D = \\sqrt{${(X2 - X1) ** 2} + ${(Y2 - Y1) ** 2}}$`}</Latex>
            <br /><br />
            <Latex>{`$D = \\sqrt{${(X2 - X1) ** 2 + (Y2 - Y1) ** 2}}$`}</Latex>
            <br /><br />
            <Latex>{`$D = ${formatSquareRoot((X2 - X1) ** 2 + (Y2 - Y1) ** 2).outer}\\sqrt{${formatSquareRoot((X2 - X1) ** 2 + (Y2 - Y1) ** 2).inner}}$`}</Latex>
          </p>
        </div>,
    });

I don't know if this is exactly what you are looking for, but your question sounds similar. I guess you can use this idea to store JSX elements in a state and render them in your component. If you have a list of JSX elements, you may use the JSX.Element[] type for them (if you use typescript) and map them

{items &&
    items.map((Item, i) => (
        <div key={i}>
            <Item />
        </div>
     ))}

Again, I am not much experienced with this and don't know if it is the best practice but it sure works.

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