Anonymous Australian
Anonymous Australian

Reputation: 103

React not rendering all elements within a list of components

I have a system in which when the user presses a button, a new component is pushed to a list of components and the state is updated. I render the list of components using {}, but only the first element is rendered.

I've used console.log to ensure that my list is actually updating. All the questions I've seen so far for this problem involve using a class that extends React.Component. Since I'm using a function to render, I don't see how I can use those solutions

export default function ExampleManager() {

    const [examples, setExamples] = React.useState([<Example key={0}/>);

    function handleClick() {
        examples.push(<Example key={examples.length}/>);
        setExamples(examples);
    }

  return (
    <>
        {examples}
        <Button variant="outlined" color="primary" onClick={handleClick}>
            Add Example
        </Button>
    </>
  );
}

If the button was to be clicked multiple times, I would expect there to be multiple Example components, however at the moment only the first element works

Upvotes: 1

Views: 308

Answers (1)

Felix
Felix

Reputation: 2681

As far as I know, examples is immutable and isn't updated by using examples.push().

Change your handleClick to the following code, to remove the reference of your example variable:

function handleClick() {
        // create a new array to prevent referencing the old on
        setExamples([
            ...examples,
            <Example key={examples.length}/>
        ]);
    }

Nonetheless you shouldn't add components per se into your array. Try to split values and its representation like the following:

function ExampleManager() {
    const [examples, setExamples] = React.useState([0]);

    const handleClick = () => setExamples([...examples, examples.length])
    return (
        <>
            {examples.map((item, key) => <Example key={key} data={item} />)}
            <Button variant="outlined" color="primary" onClick={handleClick}>
                Add Example
            </Button>
        </>
    )
}

Upvotes: 2

Related Questions