问题描述
我是一个相对较新的人,正在开发John Conway-Game of Life应用程序。我已经为电路板本身构建了Gameboard.js
功能组件(它是App.js
的子级)和Square.js
功能组件(表示电路板中的单个正方形)(并且是Gameboard
的子级和App
的孙级)。
在App
中,我有一个名为alive
的函数,当用户单击它时,我想要更改单个正方形的颜色。App
的状态中还有一个最初设置为False的""Alive""属性,alive
在调用时会将该属性更改为True。"
这里是App.js
:
import React, { Component } from 'react';
import './App.css';
import GameBoard from './GameBoard.js';
import Controls from './Controls.js';
class App extends Component {
constructor(props){
super(props);
this.state = {
boardHeight: 50,
boardWidth: 30,
iterations: 10,
reset: false,
alive: false
};
}
selectBoardSize = (width, height) => {
this.setState({
boardHeight: height,
boardWidth: width
});
}
onReset = () => {
}
alive = () => {
this.setState({ alive: !this.state.alive });
console.log('Alive function has been called');
}
render() {
return (
<div className="container">
<h1>Conway's Game of Life</h1>
<GameBoard
height={this.state.boardHeight}
width={this.state.boardWidth}
alive={this.alive}
/>
<Controls
selectBoardSize={this.selectBoardSize}
iterations={this.state.iterations}
onReset={this.onReset}
/>
</div>
);
}
}
export default App;
Gameboard
如下所示,并将pros.live传递给Square
:
import React, { Component } from 'react';
import Square from './Square.js';
const GameBoard = (props) => {
return (
<div>
<table className="game-board">
<tbody>
{Array(props.height).fill(1).map((el, i) => {
return (
<tr key={i}>
{Array(props.width).fill(1).map((el, j) => {
return (
<Square key={j} alive={props.alive}/>
);
})}
</tr>
);
})}
</tbody>
</table>
</div>
);
}
export default GameBoard;
在我的css中,我有一个名为Active的类,如果单击它,它会更改单个正方形的颜色。如何才能使Square
在Square
中,如果单击TD元素,颜色会更改(即,将CSS类更改为活动)?
我试过了:
import React, { Component } from 'react';
const Square = (props) => {
return(
<td className={props.alive ? "active" : "inactive"} onClick={() => props.alive()}></td>
);
}
export default Square;
css如下所示:
.Square {
background-color: #013243; //#24252a;
height: 12px;
width: 12px;
border: .1px solid rgba(236, 236, 236, .5);
overflow: none;
&:hover {
background-color: #48dbfb; //#00e640; //#2ecc71; //#39FF14;
}
}
.inactive {
background-color: #013243; //#24252a;
}
.active {
background-color: #48dbfb;
}
如何才能使.Square css类始终应用于每个正方形,但如果它处于活动状态,则更改单个正方形的颜色?换句话说,我是否可以将Square
的TD设置为始终使用.Square CSS类的样式,然后根据alive
在App
的状态下是否为真,对Square
中的单个元素进行适当的着色?
推荐答案
评论的想法是正确的。
您可以使用template literal并在其中嵌入三元条件句:
return (
<td
className={`Square ${props.alive ? "active" : "inactive"}`}
onClick={() => props.alive()}
></td>
);
模板文字的快速检索:使用反引号来包装一个字符串,您可以通过将其包装在${}
模式中来在其中插入一个JavaScript表达式。此外,模板文字可以跨多行,因此不再有笨拙的字符串连接!
const myName = "Abraham Lincoln";
const myString = `Some text.
This text is on the next line but still in the literal.
Newlines are just fine.
Hello, my name is ${myName}.`;
编辑:我现在看到的更大的问题是,您没有在任何地方存储每个单元格的状态。您在App
中只存储了一个名为alive
的布尔值...您真正需要的是布尔值的数组,每个布尔值表示单个Square
的状态。
"活动"状态数组应处于App
或GameBoard
,遵循"the data flows down"的反应原则。在您的情况下,您可以尝试将其保留在App
中,这样GameBoard
和Square
就可以保留纯功能组件。
在App
内部,您可以在构造函数中创建一个新的二维数组board
,并最初用0
值的子数组填充它:
// App.js
constructor(props){
super(props);
this.state = {
boardHeight: 50,
boardWidth: 30,
board: [],
iterations: 10,
reset: false,
};
this.state.board = new Array(this.state.boardHeight).fill(new Array(this.state.boardWidth).fill(0));
}
在board
数组中,每个索引代表一行。因此,[[0, 0, 1], [0, 1, 0], [1, 1, 1]]
的简化示例将表示:
0 0 1
0 1 0
1 1 1
GameBoard
应完全基于传递给它的board
道具呈现您的单元格网格,并将每个Square
的活跃值和回调函数作为道具传递:
const GameBoard = (props) => {
return (
<div>
<table className="game-board">
<tbody>
{this.props.board.map((row, y) => {
return <tr key={y}>
{row.map((ea, x) => {
return (
<Square
key={x}
x={x}
y={y}
isAlive={ea}
aliveCallback={this.props.alive}
/>
);
})}
</tr>;
})}
</tbody>
</table>
</div>
);
}
从那里您应该能够看到这个应用程序是如何工作的。App
存储游戏状态并渲染功能组件GameBoard
。在GameBoard
中,每个Square
根据其活动值呈现,并在点击时触发aliveCallback
。aliveCallback
应根据x
和y
属性,设置App
内部board
数组中相应值的状态。
这篇关于Reaction-使用三叉树在功能组件中应用CSS类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!