2

I'm building a new project with React. I have a component that defines several child components like this:

class TimeStepDisplayGraph extends React.Component {

  render () {
      return <div id={ this.props.id }>
             <TimeStepDisplayGraphNode class="graphNodeStyles"/>
             <TimeStepDisplayGraphNode class="graphNodeStyles"/>
             <TimeStepDisplayGraphNode class="graphNodeStyles"/>
             <TimeStepDisplayGraphNode class="graphNodeStyles"/>
             <TimeStepDisplayGraphNode class="graphNodeStyles"/>
             <TimeStepDisplayGraphNode class="graphNodeStyles"/>
             </div>;
    }
  }

Now ideally what I would like to do is not have the number of nodes created defined explicitly, but rather through a call like:

function createGraphNode() {
  return React.createElement( <TimeStepDisplayGraphNode class="graphNodeStyles"/>);
}

That I call x number of times. It seems like something really simple to do, and I'm sure I'll be kicking myself later for being so stupid, but at the moment I'm really at a loss for how to do this. Any help would be appreciated.

1
  • 2
    If you know how many times you need to add that component then just use a loop or map function and return the element. Commented Feb 8, 2020 at 5:10

3 Answers 3

1

There are many ways to do this. The simplest would be to simply create an array of size n and map over it, returning a React component for each one:

render () {
  const arr = new Array(6);
  return (
    <div id={ this.props.id }>
      {arr.map((ea, i) => {
        return <TimeStepDisplayGraphNode key={i} class="graphNodeStyles"/>
      }}
    </div>
  );
}

Note that you need to add the key prop to each created node to uniquely identify it between renders. Using i is normally not ideal (because it does not actually uniquely identify which node is which) but in the absence of any other identifying data it will do.

This is a very common pattern in React - see the official docs for more info.

Sign up to request clarification or add additional context in comments.

Comments

1

You can just put it in a function, like you are thinking, but you don't need the React.createElement. Something like this would suffice:

class TimeStepDisplayGraph extends React.Component {
  ...
  render () {
      return (
        <div id={ this.props.id }>
          {createGraphNode()}
        </div>
      )
    }
  }
  ...
}

function createGraphNode() {
  return <TimeStepDisplayGraphNode class="graphNodeStyles"/>;
}

Or to add it n times, something like:

class TimeStepDisplayGraph extends React.Component {
  ...
  render () {
      return (
        <div id={ this.props.id }>
          {Array.from({ length: n }, createGraphNode)}
        </div>
      )
    }
  }
  ...
}

function createGraphNode(_, index) {
  return <TimeStepDisplayGraphNode key={index} class="graphNodeStyles"/>;
}

Is that what you had in mind?

Comments

0

Yep, Muhammad is right. This is how to use a loop to do what you're asking:

class outerComponent extends React.Component {
  constructor (props) {
    super(props);
    this.state = {
      numberOfTimestamps: 100000  // (just kidding, make that smaller!)
    }
  }
  render () {
    let myTimestamps = []
    for (let i=0; i < this.state.numberOfTimestamps; i++) {
      myTimestamps.push(<TimeStepDisplayGraphNode class="graphNodeStyles"/>)
    }
    return (
      <div>
        {myTimestamps}
      </div>
    )
  }
}

Edit: Changed to for loop rather than forEach. Cannot forEach a number!

1 Comment

Numbers do not have forEach on them. This is not correct. (It's fine now that you edited it 👍🏼)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.