我对React还是比较陌生的,他正在开发John Conway-Life of Life应用程序。我为板子本身构建了Gameboard.js
功能组件(是App.js
的子组件),并为板子中的单个正方形构建了Square.js
功能组件(并且是{ Gameboard
和App
的孙代。)
在App
中,我有一个名为alive
的函数,当用户单击它时,我想更改单个正方形的颜色。 App
还具有一个“活动”属性,其状态最初设置为false,而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
看起来像这样,并将props.alive传递给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
中单击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类设置样式,然后根据Square
是否为alive
中的各个元素进行适当的着色在App
的状态下为真?
是否存在三元方法来始终设置一个特定的CSS类,然后再设置2个其他类中的1个。会始终显示Square CSS类,并根据逻辑/状态来呈现活动或不活动状态?
答案 0 :(得分:2)
评论的想法正确。
您可以使用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
。您真正需要的是布尔值的 array ,每个布尔值代表单个{{ 1}}。
遵循"the data flows down"的React原则,“有效”状态的数组应位于Square
或App
中。在您的情况下,您可以尝试将其保留在GameBoard
中,这样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
。 {p}应当根据其aliveCallback
和aliveCallback
属性在board
内部的App
数组中设置适当值的状态。
答案 1 :(得分:0)
您可以喜欢
return(
<td className={`Square ${props.alive ? "active" : "inactive"}`}
onClick={() => props.alive()}>
</td>
);
请参阅此code
答案 2 :(得分:0)
标题问题不是“无法正常工作”的真正原因
注意:此声明
className = {props.alive吗? “ active”:“ inactive”}
是正确的,不需要使用模板文字。
您可以通过多种方式编写/使用它:
className={'Square '+ (props.alive ? 'active' : 'inactive')}
说实话,由于“正方形”具有相同的背景色,因此无需使用“无效”。
className={'Square '+ (props.alive ? 'active' : null)}
事实上不需要三元运算符
className={'square '+ (props.alive && 'active')}
当然,您可以在返回之前用普通js'计算/准备'值
const Square = (props) => {
let classes = ['Square','bb']
if( props.alive ) classes.push('active')
classes = classes.join(' ')
return (
<h1 className={classes}>Hello</h1>
)};
只需阅读docs或Google,即可了解“在js中反应CSS”。