React.js 事件需要点击 2 次才能执行 [英] React.js events need 2 clicks to execute
问题描述
我正在通过 React.js 构建生命游戏,但我陷入了一种不舒服的境地:我设置为 onClick={ event }
的每个事件都需要点击 2 次才能执行.
让我详细描述一下:正如你在我下面的代码中看到的,我有 2 个按钮(一个按钮是将板的大小更改为 10 x 10,另一个是更改间隔的速度).
一切都很好,只是当我点击这两个按钮时,我需要双击才能执行.第一次点击,使用Chrome中的React Developer Tool,可以看到width、height、speed
等状态发生了变化,但board
状态仍然保持不变.只有在第二次点击后,board
状态才会改变.
谁能解释原因并告诉我如何解决?谢谢
这是我的代码的一部分
var GameBoard = React.createClass({getInitialState:函数(){返回 {宽度:10,高度:10,木板: [],速度:1000,};},//清除棋盘到初始状态清除:功能(宽度,高度){this.setState({宽度:宽度,高度:高度,});this.setSize();clearInterval(this.game);},//设置板的大小设置大小:函数(){var 板 = [];for (var i = 0; i < this.state.height; ++i) {var line = [];for (var j = 0; j <Environment board={ this.state.board } onChangeSquare = { this.onChangeSquare }/><div className="size"><h2>大小</h2><button className="btn btn-default" onClick={ this.smallSize }>小 (10 x 10)</button>
<div className="速度"><h2>速度</h2><button className="btn btn-default" onClick={ this.changeSpeed.bind(this, 900) }>慢</button>
)}});
原因是组件的状态不会立即改变.
在 clear() 方法中,您设置宽度和高度状态.但是在内部,当他们对 setSize() 方法做出反应时,他们不会立即更新.只有在到达 render 方法时才会更新.
当您第二次单击该按钮时,状态就会正确更新.这就是它在第二个实例中起作用的原因.
一种解决方案请不要保留宽度和高度,因为状态在道具中使用它.保留 10 * 10 作为单独的默认属性并在 setSize 方法中使用它.
I am building the Game of Life by React.js and I get stuck in a uncomfortable situation:
Every event which I set as onClick={ event }
needs 2 clicks to execute.
Let me describe more: As you can see in my code below, I have 2 buttons (one button is to change the size of the board to 10 x 10, the other one is to change the speed of the interval).
Everything is fine, except that when I click on these two buttons, I need to double click to execute. On the first click, with React Developer Tool in Chrome, I can see that the states including width, height, speed
are changed, but the state board
still remains unchanged. Only after the second click, the board
state is changed.
Anyone can explain why and show me how to fix? Thank you
Here is a part of my code
var GameBoard = React.createClass({
getInitialState: function() {
return {
width: 10,
height: 10,
board: [],
speed: 1000,
};
},
// clear the board to the initial state
clear: function(width, height) {
this.setState({
width: width,
height: height,
});
this.setSize();
clearInterval(this.game);
},
// set the size of the board
setSize: function() {
var board = [];
for (var i = 0; i < this.state.height; ++i) {
var line = [];
for (var j = 0; j < this.state.width; ++j)
line.push(0);
board.push(line);
}
this.setState({
board: board
});
},
// start the game
start: function() {
this.game = setInterval(this.gameOfLife, this.state.speed);
},
gameOfLife: function() { // game of life },
// change the speed of the game
changeSpeed: function(speed) {
this.setState({ speed: speed });
clearInterval(this.game);
this.start();
},
// change the size to 10 x 10
smallSize: function() {
this.clear(10, 10);
},
render: function() {
return (
<div className="game-board">
<h1>Conway's Game of Life</h1>
<h2>Generation: { this.state.generation }</h2>
<div className="control">
<button className="btn btn-default" onClick={ this.start }>Start</button>
</div>
<Environment board={ this.state.board } onChangeSquare = { this.onChangeSquare }/>
<div className="size">
<h2>Size</h2>
<button className="btn btn-default" onClick={ this.smallSize }>Small (10 x 10)</button>
</div>
<div className="speed">
<h2>Speed</h2>
<button className="btn btn-default" onClick={ this.changeSpeed.bind(this, 900) }>Slow</button>
</div>
</div>
)
}
});
The reason is that the state of a component does not change immediately.
In clear() method you set the width and height state. But internally when they react setSize() method they will not be updated immediately. They will be updated only when they reach the render method.
When you click the button the second time the states would have been updated properly. That is why it works in the second instance.
One solution please dont keep the width and height as state use it in props. Keep the 10 * 10 as a separete default prop and use it in the setSize method.
这篇关于React.js 事件需要点击 2 次才能执行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!