reactjs - 如何在我的代码中修复 setState() 调用 render()
问题描述
使用以下代码,我得到错误:
警告:在现有状态转换期间无法更新(例如在 内render
)。渲染方法应该是 props 和 state 的纯函数。
我知道为什么。我在 <BoradRow> 中调用 setState() 并且该函数再次重新渲染我的代码,这导致了无限循环。在这种情况下,解决方案可以使用像 onclick/onchange 这样的事件,但我的防止无限循环的“事件”是 Math.random 那么我应该怎么做才能停止看到这个错误?
应用程序.js
import React from 'react';
import Board from '../../Components/Board/Board';
import './App.css';
class App extends React.Component {
constructor() {
super();
this.state = {
rows: 3,
columns: 3,
fruit: null,
snake: []
};
}
SetFruitSquareID = (prevFruitID) => {
const { rows, columns } = this.state;
const maxSquareID = (rows+2) * (columns+2) - 1;
let newFruitID = Math.floor(Math.random() * maxSquareID) + 1;
while (prevFruitID === newFruitID) {
newFruitID = Math.floor(Math.random() * maxSquareID) + 1;
}
this.setState({fruit: newFruitID});
return newFruitID;
}
componentDidMount() {
if (!this.state.fruit) { //first fruit update
this.SetFruitSquareID(null);
}
}
render() {
const { rows, columns, fruit } = this.state;
return (
<div className="App">
<h1>Smart Snake !</h1>
<Board
rows={rows}
columns={columns}
fruitID={fruit}
SetFruitSquareID={this.SetFruitSquareID}
/>
</div>
);
}
}
export default App;
Board.js
import React from 'react';
import BoardRow from '../BoardRow/BoardRow';
const boardStructure = (rows) => {
let isBorderRow = [];
for (let i = 0; i < rows+2; i++) {
if (i === 0 || i === rows+1) {
isBorderRow.push(true);
} else {
isBorderRow.push(false);
}
}
return isBorderRow;
}
const Board = ({ rows, columns, fruitID, SetFruitSquareID }) => {
const board = boardStructure(rows);
let BoardRowID = 0;
return (
<div className='Board'>
{
board.map(isBorderRow => (
<BoardRow
key={BoardRowID}
rowCounter={BoardRowID++}
rows={rows}
columns={columns}
borderRow={isBorderRow}
fruitID={fruitID}
SetFruitSquareID={SetFruitSquareID}
/>
))
}
</div>
)
}
export default Board;
BoardRow.js
import React from 'react';
import Square from '../Square/Square';
import './BoardRow.css';
let squaresID = 0;
const checkSquareStatus = (fruitID, j, columns, borderRow, SetFruitSquareID) => {
let isFruitSquare = (fruitID === squaresID);
const isBorderSquare = (j===0 || j===columns+1 || borderRow);
while (isFruitSquare && isBorderSquare) {
fruitID = SetFruitSquareID(fruitID);
isFruitSquare = (fruitID === squaresID);
}
if (isFruitSquare) {
return 'fruit';
} else if (isBorderSquare) {
return 'boardBorder';
}
return 'emptyCell';
}
const rowStructure = (columns, isLastRow, borderRow, fruitID, SetFruitSquareID) => {
let boardRow = [];
for (let j = 0; j < columns+2; j++) {
boardRow.push({
id: squaresID,
status: checkSquareStatus(fruitID, j, columns, borderRow, SetFruitSquareID)
});
squaresID++;
if (isLastRow && (j === (columns+1))) {
squaresID = 0;
}
}
return boardRow;
}
const BoardRow = ({ rows, columns, rowCounter, borderRow, fruitID, SetFruitSquareID }) => {
const isLastRow = (rowCounter === rows+1);
const boardRow = rowStructure(columns, isLastRow, borderRow, fruitID, SetFruitSquareID);
return (
<div className='BoardRow'>
{
boardRow.map(square => {
const { id, status } = square;
return (
<Square
key={id}
id={id}
rows={rows}
columns={columns}
status={status}
/>
);
})
}
</div>
)
}
export default BoardRow;
解决方案
推荐阅读
- r - 将图像插入 gt 表
- python - 泊松函数与直方图数据的曲线拟合和
- snakemake - 运行多个snakemake规则
- ffmpeg - -b 标志未在 FFMpeg 中解释
- c++ - 从文件写入字符串数组指针时出错(读取访问冲突)?CPP
- asp.net - 从 S3 中删除存储桶时的随机行为
- python - Sqlalchemy - 如何在 self 不可用的上下文中定义 scopefunc?
- mysql - 关系问题 (PHPMyAdmin) - 添加键,在关系视图中不可见
- azure - 如何在 Azure 数据工厂管道中直接转换 JSON 数据
- python - 如何创建一个函数来查找字典中的所有回文(包括 i 和 a)?