我正在ES6中用箭头函数重写ReactJS的"starter game"(以消除对.bind()
,类属性和打字稿的使用。
很明显,我的代码handleSquareClick
是在渲染时触发的,因此执行了setState
,从而导致错误
错误:超出最大更新深度。当组件重复调用componentWillUpdate或componentDidUpdate内部的setState时,可能会发生这种情况。 React限制了嵌套更新的数量,以防止无限循环。
为什么?
Game.tsx :
import React, { PureComponent } from 'react';
import Board from "../Board";
class Game extends PureComponent {
state = {
history: [{
squares: Array(9).fill(null)
}],
currentStep: 0,
xIsNext: true
};
handleSquareClick = (i) => {
console.log(i);
// ...more code here
this.setState({
history: [...historyClone, { squares }],
currentStep: historyClone.length,
xIsNext: !xIsNext
});
};
render() {
const { history, currentStep } = this.state;
const current = history[currentStep];
return (
<div>
{ }
<Board
squares={current.squares}
handleSquareClick={this.handleSquareClick}
<
);
}
}
export default Game;
Board.tsx
import React, {PureComponent} from 'react';
import {
Title,
Square
} from './styles';
class Board extends PureComponent {
getSquareStringValue(value) {
if (value === 0) return 'X';
else if (value === 1) return 'O';
else return '';
}
renderSquare(props) {
const { key, value } = props;
return (
<Square
key={key}
className="square"
onClick={this.props.handleSquareClick(value)}>
{ this.getSquareStringValue(value) }
</Square>
)
}
render() {
const { title, squares } = this.props;
return (
<div className="board">
<Title>{title}</Title>
<div>
{[...Array(3).keys()]
.map((i) => (
<div className="board-row" key={i}>
{[...Array(3).keys()]
.map((j) => this.renderSquare({
key: (i+1)*(j+1),
value: squares[i]
}))
}
</div>
))
}
</div>
</div>
)
}
static defaultProps = {
title: "Board",
};
}
export default Board;
Board / styles.ts
import styled from 'styled-components';
export const Title = styled.h1`
font-size: 1rem;
`;
export const Square = styled.div`
height: 16px;
width: 16px;
border: 1px solid #000;
display: inline-block;
`;
答案 0 :(得分:2)
您只需要更改以下内容即可:
onClick={this.props.handleSquareClick(value)}>
对此:
onClick={()=> this.props.handleSquareClick(value)}>
因为onClick
期望函数作为值,但是您正在做的是调用此函数。
我们知道,如果将()放在函数的末尾,则会调用该函数。因此,我更改的是通过使用() => ...
箭头函数来传递函数而不调用它。