Generating components in React

Generating components in React
0

#1

What is “properer” way?
I’ve got this code which should generate 3x3 “grid” but it doesn’t:

squared = () => {
		
		let ttt = [];
		
		for(let i=0;i<3;i++){
			ttt.push(<div className="board-row" key={i}>);

				if(i>0){
					for(let j=(i+2);j<(i+5);j++){
						ttt.push(this.renderSquare(j));
					}
				}
				else{
					for(let j=0;j<3;j++){
						ttt.push(this.renderSquare(j));
					}
				}

			ttt.push(</div>);
		}
		return ttt;
	}

and by calling in return statement like this:

return (
      <div>
		{this.squared}
      </div>
    );

Instead it shows me

.

Correct code that i got, that doesn’t generate programatically is:

    const row1=<div className="board-row" key={1}>{this.renderSquare(0)}{this.renderSquare(1)}{this.renderSquare(2)}</div>;
	const row2=<div className="board-row" key={2}>{this.renderSquare(3)}{this.renderSquare(4)}{this.renderSquare(5)}</div>;
	const row3=<div className="board-row" key={3}>{this.renderSquare(6)}{this.renderSquare(7)}{this.renderSquare(8)}</div>;
	const rows=[row1,row2,row3];

Which i call like this:

return (
      <div>
		{rows}
      </div>
    );

Second one works, first one shows an error on for loop, why?


#2

squared is a function. Did you try calling the function?

{this.squared()}

If this does not resolve your issue, can you provide a link to your project code, so I can take a closer look at what could be going on?


#3

Here it is. I was doing this in loops because one of the subtasks is to do without hardcoding squares. It’s tutorial from official React documentation page.


#4

Using nested for loops, you could do something like the following.

  squared = () => {
    const rows = [];
    for (let i = 0; i < 3; i++) {
      const cols = [];
      for (let j = 0; j < 3; j++) {
        cols.push(this.renderSquare(i * 3 + j));
      }
      rows.push(
        <div className="board-row" key={i}>{cols}</div>
      );
    }
    return rows;
  };

It would be more readable using map instead.

  squared = (arr = [0, 1, 2]) => arr.map(row => (
    <div className="board-row" key={row}>
      {arr.map(col => this.renderSquare(row * 3 + col))}
    </div>
  ))    

#5

Thank you. Care to explain why was error in for loop?


#6

In your original nested for loop code, you only had one array instead of an array of arrays. Plus, your outer for loop was not pushing a component. You were trying to build the row divs as if they were strings or something. The inner for loop logic was close but your for loop for dealing with i > 0 was not correct, so there would have been two squares with a key of 4 and two squares with a key of 5 and no squares with a key of 7 or 8. I added console.log statements so you can see what value of j would have been passed to the renderSquare method.

Assuming you could fix the one for loop’s logic, your code would display something if you then pushed ttt to another array to be ultimately returned by the squared method. For example, with a couple of modifications (see comments) to your original code, you could have used the following. Remember, the code below still has a bug due to the first inner for loops logic, but you will at least understand how you could have properly displayed the row.

  squared = () => {
    const finalArr = []; // array to contain the rows of squares

    for (let i = 0; i < 3; i++) {
      let ttt = []; // array to contain a set of three squares

      if (i > 0) {
        for (let j = i + 2; j < i + 5; j++) {  // this for loop logic is not correct
          console.log(j);
          ttt.push(this.renderSquare(j));
        }
      } else {
        for (let j = 0; j < 3; j++) {
          console.log(j);
          ttt.push(this.renderSquare(j));
        }
      }
      finalArr.push(
        <div className="board-row" key={i}>{ttt}</div>
      );
    }
    return finalArr;
  }

#7

Well that was just the thing. I couldn’t progress 'cause that error, thus couldn’t check if rest of logic after

is valid.


#8

The real issue was the line above:

ttt.push(<div className="board-row" key={i}>);

You attempted to push half a component. It was missing the closing /

If you would have closed it properly (see below), then you would have received an error about the ttt.push() instead. Debugging JSX code is a little trickier. You have to remember when you write html elements they are really like calling a function. It would be kind of like trying to call a function with only a ( and not the closing ).

ttt.push(<div className="board-row" key={i} />);