1

I'm trying to fill create an array of JSX objects using a 2d array to represent a game board:

const rows = [];
for (var i=0; i<8; i++) {
  rows.push(<div className="board-row">);
  for (var y=0; y<8; y++) {
    rows.push(this.renderSquare(y, i));
  }
  rows.push(</div>);
}

However, I keep getting an error:

Syntax error: Unexpected token on the line: for (var y=0; y<8; y++) { pointing at the 8.

Can anybody help me understand what I'm doing wrong?

Mayank Shukla
  • 100,735
  • 18
  • 158
  • 142
MarksCode
  • 8,074
  • 15
  • 64
  • 133
  • To understand what you're doing wrong, step back and consider what JavaScript code your JSX code, if it was valid, would transpile to. (In case you need a refresher, [here's how some valid JSX transpiles](http://babeljs.io/repl/#?babili=false&evaluate=false&lineWrap=false&presets=env%2Creact&targets=&browsers=&builtIns=false&debug=false&code_lz=DwEwlgbgBAxgNgQwM5IHIILYFMC8AiAIwHsEAnEAWlKIHc8A-AKClgAsw4RSsA7AOgGNgAenAR6QA&experimental=false&loose=false&spec=false&playground=true).) – Jordan Running Jun 23 '17 at 18:24

2 Answers2

3

div is not closed that's why it is throwing the error, each element should be properly closed.

To solve your issue, use two arrays one for rows and one for columns, first calculate the columns then put that inside the row element.

Write it like this:

var rows = [], column;
for (let i=0; i<8; i++) {
    column = [];
    for (let y=0; y<8; y++) {
        column.push(this.renderSquare(y, i));
    }
    rows.push(<div className="board-row">{column}</div>);
}

Note: Use let instead of var for i and j variables.

Check this answer for more details: What's the difference between using "let" and "var" to declare a variable?

Update:

As suggested by @Jordan Running, we should use const for rows (it's never reassigned) and let for columns, like this:

const rows = [];
for (let i=0; i<8; i++) {
    let column = [];
    for (let y=0; y<8; y++) {
        column.push(this.renderSquare(y, i));
    }
    rows.push(<div className="board-row">{column}</div>);
}
Mayank Shukla
  • 100,735
  • 18
  • 158
  • 142
  • Thanks! Is there any reason you said to use `let` instead of `var` but not `const` instead for `rows` or `column`? – MarksCode Jun 23 '17 at 18:34
  • 1
    reason for using `let` over `var` is scope, since i and j these 2 values are required inside `for loop` only so use `let`, scope of `var` is `function` level but scope of `let` is `block` level, and i used `var` for columns and rows because before the nested loop start we need to clear all the column values (previous values) for that we need to assign `[]` again to columns, if we use `const` then it will throw error. check the link for more details about scope and benefits of these three. – Mayank Shukla Jun 23 '17 at 18:43
  • 1
    @MayankShukla You should use `const` for `rows` (it's never reassigned) and `let` for `columns`. There's no advantage to using `var` here. – Jordan Running Jun 23 '17 at 23:46
  • @JordanRunning thanks for suggestion, added that in answer :) – Mayank Shukla Jun 24 '17 at 09:34
0

In the rows.push(<div className="board-row">); the compiler was expecting the body of the div followed by closing tags. JSX wont accept mismatched tags.

You must have meant this:

const rows = [];
for (var i=0; i<8; i++) {
  let inner = []
  for (var y=0; y<8; y++) {
      inner.push(this.renderSquare(y, i));
    }
  rows.push(<div className="board-row">{inner}</div>);
}

Inside the row div, have an array of squares.

Jesvin Jose
  • 22,498
  • 32
  • 109
  • 202