我很容易找到其他颜色的应用程序。游戏的目的只是从场景中选择不同的颜色。 5点后,该设置将渲染为3x3而不是2x2。但是我遇到了这个错误
“未捕获的不变违反:超过最大更新深度。当组件重复调用componentWillUpdate或componentDidUpdate内部的setState时,可能会发生这种情况。React限制嵌套更新的数量以防止无限循环。 固定为“
我试图将其上传到codepen,但是由于无限循环,一旦遇到错误,它似乎会杀死该应用程序。 我仔细阅读了这个问题,他们说componentDidUpdate中的setState可能会导致另一个更新,然后inf循环,但是我不确定我的问题是怎么引起的。
temperature = int(input("What is the temperature? "))
if temperature == 26:
print("The weather is average")
elif temperature > 26:
print("The weather is hot")
elif temperature < 26:
print("It's a cold day")
else:
print("Invalid")
componentDidUpdate() {
if (this.state.score === 4) {
this.setState({ size: 9 });
} else if (this.state.score === 9) {
this.setState({ size: 16 });
}
}
class ColorGame extends React.Component {
constructor(props) {
super(props);
this.colorSet = [['blue', '#EA401B'], ['yellow', '#34AD44'], ['green', '#80279D'], ['pink', 'purple']];
this.pickColorPair = this.pickColorPair.bind(this);
this.loadColor = this.loadColor.bind(this);
this.randomize = this.randomize.bind(this);
this.isMatch = this.isMatch.bind(this);
this.increment = this.increment.bind(this);
this.state = {
colors: [],
score: 0,
colorPair: [],
size: 4
}
}
pickColorPair() {
const randomNumber = Math.floor(Math.random() * 4);
this.setState({ colorPair: this.colorSet[randomNumber] }, () => { this.loadColor() });
}
loadColor() {
// console.log(this.state.colorPair);
let colorArray = [this.state.colorPair[0]];
for (let i = 1; i < this.state.size; i++) {
colorArray.push(this.state.colorPair[1]);
}
this.randomize(colorArray);
this.setState(() => ({ colors: colorArray }));
}
randomize(colorArray) {
for (let i = colorArray.length - 1; i > 0; i--) {
let j = Math.floor(Math.random() * (i + 1)); // random index from 0 to i
// swap elements array[i] and array[j]
// we use "destructuring assignment" syntax to achieve that
// you'll find more details about that syntax in later chapters
// same can be written as:
// let t = colorArray[i]; colorArray[i] = colorArray[j]; colorArray[j] = t
[colorArray[i], colorArray[j]] = [colorArray[j], colorArray[i]];
}
return (colorArray);
}
isMatch(color) {
let counter = 0;
//We only need to compare the first 3 to know if we got the right answer
for (let i = 0; i < 3; i++) {
if (color === this.state.colors[i]) {
counter++;
}
}
if (counter < 2) {
console.log("CORRECT!");
this.increment();
this.pickColorPair();
this.loadColor();
} else {
console.log("INCORRECT GUESS!");
}
}
increment() {
this.setState((prevState) => ({ score: prevState.score + 1 }));
console.log(this.state.score);
}
// ====== LIFE CYCLE METHODS =====================
//problem comes from this.setState taking a while // i think we can use promises to force it to resolve quicker..
componentDidUpdate() {
if (this.state.score === 4) {
this.setState({ size: 9 });
} else if (this.state.score === 9) {
this.setState({ size: 16 });
}
}
render() {
return (
<div className="container">
<h1>Spot The Difference</h1>
<h2>Score: {this.state.score}</h2>
<h2>Size: {this.state.size}</h2>
<button className='startbtn' onClick={this.pickColorPair}>Start</button>
<GameBoard
colors={this.state.colors}
isMatch={this.isMatch}
score={this.state.score} />
</div>
);
};
}
const GameBoard = (props) => (
<div className="gameboard">
{
props.colors.map((color, index) => (
<ColorCircle
key={index}
color={color}
isMatch={props.isMatch}
score={props.score}
/>
))
}
</div>
)
class ColorCircle extends React.Component {
constructor(props) {
super(props);
this.isMatch = this.isMatch.bind(this);
this.levelMode = this.levelMode.bind(this);
}
levelMode() {
console.log(this.props.score)
if (this.props.score < 5) {
return 'colorCircle-level1';
} else if (this.props.score > 9) {
return 'colorCircle-level3';
}
else if (this.props.score >= 4) {
return 'colorCircle-level2';
}
}
isMatch() {
this.props.isMatch(this.props.color);
}
render() {
return (
<div>
<button
className={this.levelMode()}
onClick={this.isMatch}
style={{ backgroundColor: this.props.color }}></button>
</div >
)
}
}
//we can pass in props to the main app through here. {} is the JSX brackets, not an object literal
ReactDOM.render(<ColorGame />, document.getElementById('app'));
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
button {
width: 50px;
height: 50px;
border-radius: 50%;
outline: none;
border: none;
}
#app {
display: block;
margin: auto;
width: 800px;
text-align: center;
}
.container {
width: 60rem;
height: 70rem;
background-color: #004d66;
margin: auto;
}
.gameboard {
display: flex;
flex-wrap: wrap;
margin: auto;
width: 30rem;
// background: white;
}
.startbtn {
margin: 3rem 0 5rem 0;
width: 8rem;
height: 8rem;
}
.colorCircle-level1 {
width: 15rem;
height: 15rem;
}
.colorCircle-level2 {
width: 10rem;
height: 10rem;
}
.colorCircle-level3 {
width: 7rem;
height: 7rem;
}
//Spacing
$s-size: 1.2rem;
$m-size: 1.6rem;
$l-size: 3.2rem;
$xl-size: 4.8rem;
$desktop-breakpoint: 45rem;
// rem (better support for accessibility)
html {
//makes rem = 10px
font-size: 62.5%;
}
body {
font-family: Helvetica, Arial, san-serif;
//now rem is 16px
font-size: $m-size;
background-color: #203c589a;
color: white;
}
button {
cursor: pointer;
}
button:disabled {
cursor: default;
}
答案 0 :(得分:1)
您可以在增加分数后立即进行检查:
if (counter < 2) {
console.log("CORRECT!");
this.increment();
this.upgrade();
this.pickColorPair();
this.loadColor();
}
升级功能:
upgrade() {
if (this.state.score === 4) {
this.setState({
size: 9
});
} else if (this.state.score === 9) {
this.setState({
size: 16
});
}
}
在构造函数中绑定它:
this.upgrade = this.upgrade.bind(this);
class ColorGame extends React.Component {
constructor(props) {
super(props);
this.colorSet = [
['blue', '#EA401B'],
['yellow', '#34AD44'],
['green', '#80279D'],
['pink', 'purple']
];
this.pickColorPair = this.pickColorPair.bind(this);
this.loadColor = this.loadColor.bind(this);
this.randomize = this.randomize.bind(this);
this.isMatch = this.isMatch.bind(this);
this.increment = this.increment.bind(this);
this.upgrade = this.upgrade.bind(this);
this.state = {
colors: [],
score: 0,
colorPair: [],
size: 4
}
}
pickColorPair() {
const randomNumber = Math.floor(Math.random() * 4);
this.setState({
colorPair: this.colorSet[randomNumber]
}, () => {
this.loadColor()
});
}
loadColor() {
// console.log(this.state.colorPair);
let colorArray = [this.state.colorPair[0]];
for (let i = 1; i < this.state.size; i++) {
colorArray.push(this.state.colorPair[1]);
}
this.randomize(colorArray);
this.setState(() => ({
colors: colorArray
}));
}
randomize(colorArray) {
for (let i = colorArray.length - 1; i > 0; i--) {
let j = Math.floor(Math.random() * (i + 1)); // random index from 0 to i
// swap elements array[i] and array[j]
// we use "destructuring assignment" syntax to achieve that
// you'll find more details about that syntax in later chapters
// same can be written as:
// let t = colorArray[i]; colorArray[i] = colorArray[j]; colorArray[j] = t
[colorArray[i], colorArray[j]] = [colorArray[j], colorArray[i]];
}
return (colorArray);
}
isMatch(color) {
let counter = 0;
//We only need to compare the first 3 to know if we got the right answer
for (let i = 0; i < 3; i++) {
if (color === this.state.colors[i]) {
counter++;
}
}
if (counter < 2) {
console.log("CORRECT!");
this.increment();
this.upgrade();
this.pickColorPair();
this.loadColor();
} else {
console.log("INCORRECT GUESS!");
}
}
increment() {
this.setState((prevState) => ({
score: prevState.score + 1
}));
console.log(this.state.score);
}
upgrade() {
if (this.state.score === 4) {
this.setState({
size: 9
});
} else if (this.state.score === 9) {
this.setState({
size: 16
});
}
}
render() {
return ( <
div className = "container" >
<
h1 > Spot The Difference < /h1> <
h2 > Score: {
this.state.score
} < /h2> <
h2 > Size: {
this.state.size
} < /h2> <
button className = 'startbtn'
onClick = {
this.pickColorPair
} > Start < /button> <
GameBoard colors = {
this.state.colors
}
isMatch = {
this.isMatch
}
score = {
this.state.score
}
/> <
/div>
);
};
}
const GameBoard = (props) => ( <
div className = "gameboard" > {
props.colors.map((color, index) => ( <
ColorCircle key = {
index
}
color = {
color
}
isMatch = {
props.isMatch
}
score = {
props.score
}
/>
))
} <
/div>
)
class ColorCircle extends React.Component {
constructor(props) {
super(props);
this.isMatch = this.isMatch.bind(this);
this.levelMode = this.levelMode.bind(this);
}
levelMode() {
console.log(this.props.score)
if (this.props.score < 5) {
return 'colorCircle-level1';
} else if (this.props.score > 9) {
return 'colorCircle-level3';
} else if (this.props.score >= 4) {
return 'colorCircle-level2';
}
}
isMatch() {
this.props.isMatch(this.props.color);
}
render() {
return ( <
div >
<
button className = {
this.levelMode()
}
onClick = {
this.isMatch
}
style = {
{
backgroundColor: this.props.color
}
} > < /button> <
/div >
)
}
}
//we can pass in props to the main app through here. {} is the JSX brackets, not an object literal
ReactDOM.render( < ColorGame / > , document.getElementById('app'));
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
button {
width: 50px;
height: 50px;
border-radius: 50%;
outline: none;
border: none;
}
#app {
display: block;
margin: auto;
width: 800px;
text-align: center;
}
.container {
width: 60rem;
height: 70rem;
background-color: #004d66;
margin: auto;
}
.gameboard {
display: flex;
flex-wrap: wrap;
margin: auto;
width: 30rem;
// background: white;
}
.startbtn {
margin: 3rem 0 5rem 0;
width: 8rem;
height: 8rem;
}
.colorCircle-level1 {
width: 15rem;
height: 15rem;
}
.colorCircle-level2 {
width: 10rem;
height: 10rem;
}
.colorCircle-level3 {
width: 7rem;
height: 7rem;
}
//Spacing
$s-size: 1.2rem;
$m-size: 1.6rem;
$l-size: 3.2rem;
$xl-size: 4.8rem;
$desktop-breakpoint: 45rem;
// rem (better support for accessibility)
html {
//makes rem = 10px
font-size: 62.5%;
}
body {
font-family: Helvetica, Arial, san-serif;
//now rem is 16px
font-size: $m-size;
background-color: #203c589a;
color: white;
}
button {
cursor: pointer;
}
button:disabled {
cursor: default;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" href="~/favicon.ico">
<title>Spot The Difference</title>
</head>
<body>
<div id="app"></div>
<script src="/bundle.js"></script>
</body>
</html>
答案 1 :(得分:0)
在评论中回答。在isMatch中移动了代码或将其保留在componentDidUpdate中,但还对代码进行了条件检查以检查prevState