[英]React setState renders component twice when called
I'm trying to build a connect 4 game, which has a Board component comprised of 7 Column components all contain 6 Space components. 我正在尝试构建一个connect 4游戏,它有一个由7个Column组件组成的Board组件,每个组件都包含6个Space组件。 Every Column has a Drop button above it, which will be used to drop the piece into the column.
每个列上方都有一个Drop按钮,用于将该块放入列中。 In order to alternate between "red" and "black" players, I have created a state "redOrBlue" which returns a boolean.
为了在“红色”和“黑色”玩家之间交替,我创建了一个状态“redOrBlue”,它返回一个布尔值。
In a nutshell, when the Drop button is clicked, I want to toggle the value of "redOrBlue" to keep track of whose turn it is. 简而言之,当单击“下拉”按钮时,我想切换“redOrBlue”的值以跟踪它的转向。 I've set the onClick function to setState({redOrBlue: !this.state.redOrBlue)}, however, calling this function will cause react to render an extra column right below the column in which the button was clicked.
我已经将onClick函数设置为setState({redOrBlue:!this.state.redOrBlue)},但是,调用此函数将导致react在单击按钮的列的正下方呈现一个额外的列。 I understand that setState automatically re-renders the DOM, but how can I keep from it rendering duplicates of a component?
我知道setState会自动重新呈现DOM,但是如何保持它不会呈现组件的重复? Thanks for your help!
谢谢你的帮助!
class Column extends Component{
constructor(){
super();
this.state = {
myArray: [],
buttonArray: [],
buttonNumber: null,
newArray: [],
redOrBlue: true
}
}
makeRow(){
var component = <Space className="space"/>
for(var i = 0; i < 6; i++){
this.state.myArray.push(component);
}
}
handleClick(){
var num = this.props.colNumber;
var array = this.props.boardArray[num];
var boolean = false;
var color;
if(this.state.redOrBlue === true){
color = "red"
}else{
color = "black"
}
for(var i = 5; i > -1; i--){
if(boolean === false){
if(array[i] === null){
array[i] = color;
boolean = true;
}
}
}
this.setState({redOrBlue: !this.state.redOrBlue})
console.log(array)
}
render(){
{this.makeRow()}
return(
<div className="column">
<DropButton onClick={() => this.handleClick()} id={'button-' + this.props.colNumber} buttonNumber={this.props.colNumber} className={this.props.className}/>
{this.state.myArray.map(function(component, key){
return component
})}
</div>
)
}
}
Remove {this.makeRow()}
from your render function. 从渲染函数中删除
{this.makeRow()}
。 All you're doing is adding another row to the state, in a rather non-kosher method, every time the component renders. 你所做的就是每次组件渲染时,以一种非犹太方法向状态添加另一行。 Try something like this:
尝试这样的事情:
constructor(){
super();
this.state = {
myArray: [],
buttonArray: [],
buttonNumber: null,
newArray: [],
redOrBlue: true
}
this.makeRow();
}
makeRow(){
var tempArray = [];
var component = <Space className="space"/>
for(var i = 0; i < 6; i++){
tempArray.push(component);
}
this.setState({ myArray: tempArray }};
}
There are many things that you need to change in your code: 您需要在代码中更改许多内容:
*First of all never store the ui items
in state variable, state
variable should contain only data and values. *首先永远不要将
ui items
存储在状态变量中, state
变量应该只包含数据和值。
*Never do any changes in state
variable by this.state.a = '' or this.state.a.push({})
, always treat the state
values as immutable and use only setState
to change the value. *不要通过
this.state.a = '' or this.state.a.push({})
对state
变量进行任何更改,始终将state
值视为不可变,并仅使用setState
更改值。
*Always call function inside render
that will create the ui part
directly if you want to create something dynamically
. *如果你想
dynamically
创建东西,总是在render
中调用函数,直接创建ui part
。
Call makeRow
method from render and it will return the ui directly without storing it in state variable, like this: 从render调用
makeRow
方法,它将直接返回ui而不将其存储在状态变量中,如下所示:
makeRow(){
var component = [];
for(var i = 0; i < 6; i++){
component.push(<Space key={i} className="space"/>);
}
return component;
}
render(){
return(
<div className="column">
<DropButton onClick={() => this.handleClick()} id={'button-' + this.props.colNumber}
buttonNumber={this.props.colNumber} className={this.props.className}/>
{this.makerow()}
</div>
)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.