2

I want to create n instances of a React component.

What is a good terse way to do this give that JSX can only contain expressions?

I currently am trying the following:

<Wrapper>
  {repeat(n)(i => <MyComponent i={i} />}      
</Wrapper>

function repeat(n) {
    return cb => Array(n).fill(null).forEach((_, i) => cb(i));
}
Ben Aston
  • 53,718
  • 65
  • 205
  • 331
  • 'JSX can only contain expressions' isn't entirely true. I recommend doing any formatting in your render method prior to returning the formatted JSX. Also, check out the [Thinking in React tutorial](https://facebook.github.io/react/docs/thinking-in-react.html) – Dan Esparza Jul 25 '17 at 12:11
  • Ok thank you. Can you give me an example of a statement that is permitted inside JSX? – Ben Aston Jul 25 '17 at 12:48

1 Answers1

4

You can use as much JavaScript als you like :)

render() {
  const lst = [1, 2, 3, 4];
  return (
    <div>
      {lst.map(itm => <span key={itm}>{itm}</span>)}
    </div>
  );
}

If you do not have a key ready, you can use the second argument of the map callback which is the index in the array. More info on MDN.

In your specific case where you do not have an array but just a number:

render() {
  var times = [];
  for (let i = 0; i < 10; i++) {
    times.push(<MyComponent key={i} i={i} />);
  }
  return <Wrapper>{times}</Wrapper>;
}

Also check this answer on how to use for loops. It's not quite as nice but it also works. I believe the React team has planned to make working with arrays in JSX more straight forward.

If you have just a number, and do not want to use a for loop, you could also "fake" it, for example by using string.repeat. Not sure if this is very readable though :)

render() {
  return (
    <div>
      {'a'.repeat(10).split('').map((_, i) => <MyComponent i={i} />}
    </div>
  );
}
Laoujin
  • 9,962
  • 7
  • 42
  • 69
  • 1
    I've used map many times to do this. Readers observe: The 'key' attribute is important. (React will complain if you don't have it) – Dan Esparza Jul 25 '17 at 10:08
  • I guess the point of the question is that I don't have a list to map over. Instead I simply have a number. – Ben Aston Jul 25 '17 at 10:11