1

Making a React app that will show colored circles. But when I add a for loop it stopped working. That is wrong here?

I am using babel and JSX. This is an exercise from a book - Learning React by Kirupa Chinnathambi

var colors = ["#393E41", "#E94F37", "#1C89BF", "#A1D363", "#85FFC7", "#297373", "#FF8552", "#A40E4C"];

var renderData = [];

// STOPED WORKING AFTER THIS LOOP
for (var i = 0; i < colors.length; i++) {
  renderData.push(< Circle color = {colors[i]} />);
  }

  let Circle = React.createClass({
    render: function() {
      let styles = {
        background: this.props.color,
        width: 60,
        height: 60,
        borderRadius: "50%"
      }
      return ( 
      <div style={styles}></div>
      )
    }
  });

  ReactDOM.render( 
  <div> {renderData} </div>, window.add);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="add"></div>

2
  • 1
    Have you tried to place the for loop after component definition?
    – Robsonsjre
    Commented Mar 3, 2017 at 22:38
  • OMG!!!! this is such a noob mistake Commented Mar 3, 2017 at 22:40

4 Answers 4

1

The for loop should be after component definition

1

Placing the loop after the definition works for me:

var colors = ["#393E41", "#E94F37", "#1C89BF", "#A1D363", "#85FFC7", "#297373", "#FF8552", "#A40E4C"];

var renderData = [];


  let Circle = React.createClass({
    render: function() {
      let styles = {
        background: this.props.color,
        width: 60,
        height: 60,
        borderRadius: "50%"
      }
      return ( 
      <div style={styles}></div>
      )
    }
  });
  
// STOPED WORKING AFTER THIS LOOP
for (var i = 0; i < colors.length; i++) {
  renderData.push(<Circle color ={colors[i]} />);
  }

  ReactDOM.render( 
  <div> {renderData} </div>, window.add);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="add"></div>

0

Since you are working on an exercise here are some pointers:

  1. Use colors.map to return jsx where you create circle components, you can wrap this behavior in a renderCircles function
  2. You may actually create a container element called App so that ReactDOM.render becomes very trivial

Best of luck.

2
  • 1
    1) Ok =) 2) I have this in my HTML <div id="add"></div> Also the script works fine without the loop. Like this ReactDOM.render(<div> <Circle color="#E94F37" /> </div>, window.add); =(( Commented Mar 3, 2017 at 22:37
  • Since @paqash is learning, I was trying to also point him towards best practices. Commented Mar 3, 2017 at 22:46
0

Basically, you use the <Circle> component, which is not initialized yet. Other words, you try to access Circle, but its value is undefined.

JavaScript has a language feature called hoisting, which allows you to reference variables and functions before you declare them but result can be really surprising if you don't understand hoisting rules.

Briefly, JS interpreter puts all variables and functions declaration to the top of the scope they declared in. For example, code:

console.log(a)
let a = 1; 

is interpreted as:

let a;
console.log(a)  // value of a is undefined here 
a = 1;

To fix you example just move your component definition above the code which uses it.

let Circle = React.createClass({
  render: function() {
    let styles = {
      background: this.props.color,
      width: 60,
      height: 60,
      borderRadius: "50%"
    }
    return ( 
      <div style={styles}></div>
    )
  } 
});

for (var i = 0; i < colors.length; i++) {
  renderData.push(< Circle color = {colors[i]} />);
}

Not the answer you're looking for? Browse other questions tagged or ask your own question.