I just finished the basic react tic tac toe tutorial and I modified the base code so I can dynamically generate n x n tic tac toe grids. Currently I'm using flexbox to format my "grid" of buttons and I'm running into an issue where flexbox column appears to be adding a margin between entities. I'm not sure why this is the case. Additionally, when I click on every element in a row, react rerenders the entire row with the correct margins. Below is my css and javascript.
function Square(props) {
return (
<button className="square" onClick={props.onClick}>
{props.value}
</button>
);
}
class Board extends React.Component {
// essentially these are fields that store the state of the board
constructor(props) {
super(props);
this.state = {
squares: Array(16).fill(null),
xIsNext: true
};
}
// generate row
generateRow(j) {
var i;
var columns = 4;
var row = [];
for (i = 0; i < columns; i++) {
row.push(
<div key={i + columns * j}> {this.renderSquare(i + columns * j)} </div>
);
}
return row;
}
// create board
renderBoard() {
var i;
var rows = 4;
var board = [];
for (i = 0; i < rows; i++) {
board.push(<div className="board-row"> {this.generateRow(i)}</div>);
}
return board;
}
handleClick(i) {
const squares = this.state.squares.slice();
if (squares[i]) {
return;
}
squares[i] = this.state.xIsNext ? "X" : "O";
this.setState({
squares: squares,
xIsNext: !this.state.xIsNext
});
}
renderSquare(i) {
return (
<Square
value={this.state.squares[i]}
onClick={() => this.handleClick(i)}
/>
);
}
render() {
let status;
status = "Next player " + (this.state.xIsNext ? "X" : "O");
return (
<div>
<div className="status">{status}</div>
{this.renderBoard()}
</div>
);
}
}
class Game extends React.Component {
render() {
return (
<div className="game">
<div className="game-board">
<Board />
</div>
</div>
);
}
}
// ========================================
ReactDOM.render(<Game />, document.getElementById("root"));
body {
font: 14px "Century Gothic", Futura, sans-serif;
margin: 20px;
}
ol,
ul {
padding-left: 30px;
}
.status {
margin-bottom: 10px;
}
.square:focus {
outline: none;
}
.kbd-navigation .square:focus {
background: #ddd;
}
.game-info {
margin-left: 20px;
}
.game-board {
display: flex;
flex-direction: column;
}
.board-row {
display: flex;
flex-direction: row;
margin-bottom: -1px;
}
.square {
background: #fff;
border: 1px solid #999;
font-size: 24px;
font-weight: bold;
line-height: 34px;
height: 40px;
padding: 0;
text-align: center;
width: 40px;
margin-right: -1px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
<div id="root"></div>