1

I have an array populated with a list of random numbers e.g. array = [1,6,8,7,3,5,5,2,3,0]

I would like to render multiple copies of the same component, where the exact quantity is equal to each number in the array i.e. once, six times, eight times and so on, inside the DOM. Ideally each set of components would sit inside a <div /> in order to separate them, something like this:

<div><Drop /></div>
<div><Drop /> ... duplicated 5 more times </div>
<div><Drop /> ... duplicated 7 more times </div>
//... and so on

I found a useful line of code from this question: Array.from({ length: 5 }, (_, index) => <MyComponent key={index} />) which works if I drop it straight into the render method, however if I put this into a function and try calling it for each number in the array, setting the length to the item value, nothing is rendered in the DOM, also no errors.

Here is my code so far:

import {ReactComponent as Drop} from './images/raindrop.svg';

function App() {

  // a static array for the sake of simplicity
  const array = [1,6,8,7,3,5,5,2,3,0];

  const Rain = () => {
    array.forEach(getRain)
  }

  function getRain(rand) {
    Array.from({ length: rand }, (_, index) => <Drop key={index} />)
  }

  return (
    <div className="App">
      <Rain />
    </div>
  );

export default App;

}

I haven't attempted to wrap anything in a <div /> yet but if you can see a simple way to also do this then much appreciated.

Thank you for your help.

Freja
  • 49
  • 1
  • 7

1 Answers1

1

let me show you what I found in your code

  1. forEach doesn't return a list. so if you want to return a list use map. Even if return array.forEach(getRain) it will be undefined
  2. Avoid using array index as the key prop. use something unique that is unlikely to change in the future (couldn't think of something good in this example). Use index as a last resort if no unique key is available.
  3. The way you have written the function requires you to write return keyword explicitly. Recommend you stick to one and use it consistently. you can write either way
  const Rain = () => {
    return array.map(getRain)
  }

or

  const Rain = () => array.map(getRain)

similarly

  function getRain(rand) {
    return Array.from({ length: rand }, (_, index) => <Drop key={index} />)
  }

or

  const getRain = (rand) => Array.from({ length: rand }, (_, index) => <Drop key={index} />)

const MyComponent = ({data}) => {
  return <h3> MyComponent {data} </h3>;
}

const App = () => {
  const array = [1,6,8,7,3,5,5,2,3,0];
  const Rain = () => array.map(getRain)

  const getRain = (rand) => Array.from({ length: rand }, (_, index) => <MyComponent data={rand} key={rand+index} />)

    return (
    <div>
      <Rain />
    </div>
  );
};

ReactDOM.render(<App />, document.querySelector('.app'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div class='app'></div>

also since what you need is something like

<div><Drop /></div>
<div><Drop /> ... duplicated 5 more times </div>
<div><Drop /> ... duplicated 7 more times </div>

you might have to change getRain to something like

 const getRain = (rand) => (<div key={'need a unique key here'}> {Array.from({ length: rand }, (_, index) => <Drop key={'another unique key'} />)} </div>)
cmgchess
  • 7,996
  • 37
  • 44
  • 62
  • This is brilliant, thank you so much for your help. I need to have a think about those unique keys.. perhaps I could generate a longer random number for each key. – Freja Mar 30 '23 at 13:10
  • @Freja eventhough it is random have to make sure the key doesn't change every time. this is how react identifies which components need to rerender. maybe [this](https://stackoverflow.com/questions/39549424/how-to-create-unique-keys-for-react-elements) will help – cmgchess Mar 30 '23 at 13:14
  • Thank you the app works, I haven't fixed the key problem yet though. – Freja Apr 18 '23 at 21:01
  • @Freja if there is no unique key combining index would be last option. more about keys https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key – cmgchess Apr 18 '23 at 21:07