数组的反应状态未使用扩展运算符附加
React state for array is not appended using spread operator
我正在使用 React.js 创建数独应用程序。
我遇到了一个问题,即仅在 createSudokValues()
的第一个内循环(仅创建数独的第一行)之后才将值写入状态 sudoku
。外循环应该生成其余的行(按 setSudoku(prevSquares => [ ...prevSquares, ...row]);
)。
我错过了什么?谢谢!
import React, { useEffect, useState } from 'react';
import '../App.css';
import { SquareType } from '../interfaces/customInterfaces';
import Square from './Square';
function App() {
let row: Array<SquareType> = [];
const [sudoku, setSudoku] = useState<SquareType[]>([]);
const possibleOptionsForDigit = [1, 2, 3, 4, 5, 6, 7, 8, 9];
function generateRandomArrayIndex(unusedDigits: Array<number> ) {
return Math.floor(Math.random() * unusedDigits.length);
}
function unusedDigitInRowAndColumn( sudoku: Array<SquareType>, row: Array<SquareType>, columnIndex: number ) {
let digitsExistingInRow: Array<number> = [];
let digitsExistingInColumn: Array<number> = [];
let unusedDigitsInRow: Array<number> = [];
let unusedDigitsInColumn: Array<number> = [];
let unusedDigits: Array<number>;
let randomDigitFromUnused: number;
digitsExistingInRow = row.map(square => square.digit);
unusedDigitsInRow = possibleOptionsForDigit.filter(digit => !digitsExistingInRow.includes(digit));
digitsExistingInColumn = sudoku.filter(square => square.index === columnIndex).map(square => square.digit);
unusedDigitsInColumn = possibleOptionsForDigit.filter(digit => !digitsExistingInColumn.includes(digit));
unusedDigits = unusedDigitsInRow.filter(digit => unusedDigitsInColumn.includes(digit));
randomDigitFromUnused = unusedDigits[generateRandomArrayIndex(unusedDigits)];
return randomDigitFromUnused;
}
function createSudokValues() {
let generatedUnusedDigit: number = 0;
for ( let y = 1; y <= 9; y++ ) {
for ( let columnIndex = 1; columnIndex <= 9; columnIndex++ ) {
while (row.length <= 9) {
console.log('row ', row)
generatedUnusedDigit = unusedDigitInRowAndColumn(sudoku, row, columnIndex);
row.push(
{
digit: generatedUnusedDigit,
index: columnIndex,
shown: true
}
);
break;
}
}
// end of inner loop
// eslint-disable-next-line no-loop-func
setSudoku(prevSquares => [ ...prevSquares, ...row]);
row = [];
// end of outer loop
}
}
useEffect(() => {
console.log('sudoku ', sudoku)
});
useEffect(() => {
createSudokValues();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return (
<div className="App">
<div className="pageContainer">
<p>
Sudoku
</p>
<div className="sudokuContainer">
{
sudoku.map((square, idx) =>
<Square key={idx} {...square}></Square>
)
}
</div>
</div>
</div>
);
}
export default App;
这是打印到屏幕的第一行:
相当于第一行console.logged:
您应该在每次第一个循环运行时初始化行数组,而不是在函数内部使用变量。
所以这个函数:
function createSudokValues() {
let generatedUnusedDigit: number = 0;
for ( let y = 1; y <= 9; y++ ) {
for ( let columnIndex = 1; columnIndex <= 9; columnIndex++ ) {
while (row.length <= 9) {
console.log('row ', row)
generatedUnusedDigit = unusedDigitInRowAndColumn(sudoku, row, columnIndex);
row.push(
{
digit: generatedUnusedDigit,
index: columnIndex,
shown: true
}
);
break;
}
}
// end of inner loop
// eslint-disable-next-line no-loop-func
setSudoku(prevSquares => [ ...prevSquares, ...row]);
row = [];
// end of outer loop
}
}
应该是:
function createSudokValues() {
let generatedUnusedDigit = 0;
let row: Array<SquareType> = [];
let tempSudoku: Array<SquareType> = [];
for (let y = 1; y <= 9; y++) {
for (let columnIndex = 1; columnIndex <= 9; columnIndex++) {
while (row.length <= 9) {
console.log("row ", row);
generatedUnusedDigit = unusedDigitInRowAndColumn(
sudoku,
row,
columnIndex
);
row.push({
digit: generatedUnusedDigit,
index: columnIndex,
shown: true
});
break;
}
tempSudoku.push(...row);
row = [];
}
}
setSudoku(tempSudoku);
}
在循环内设置状态没有什么意义,因为出于性能原因,它会很糟糕,因为状态变量会触发无用的渲染。
并且您还应该删除 App 组件开头的 let row: Array<SquareType> = [];
初始化。
我正在使用 React.js 创建数独应用程序。
我遇到了一个问题,即仅在 createSudokValues()
的第一个内循环(仅创建数独的第一行)之后才将值写入状态 sudoku
。外循环应该生成其余的行(按 setSudoku(prevSquares => [ ...prevSquares, ...row]);
)。
我错过了什么?谢谢!
import React, { useEffect, useState } from 'react';
import '../App.css';
import { SquareType } from '../interfaces/customInterfaces';
import Square from './Square';
function App() {
let row: Array<SquareType> = [];
const [sudoku, setSudoku] = useState<SquareType[]>([]);
const possibleOptionsForDigit = [1, 2, 3, 4, 5, 6, 7, 8, 9];
function generateRandomArrayIndex(unusedDigits: Array<number> ) {
return Math.floor(Math.random() * unusedDigits.length);
}
function unusedDigitInRowAndColumn( sudoku: Array<SquareType>, row: Array<SquareType>, columnIndex: number ) {
let digitsExistingInRow: Array<number> = [];
let digitsExistingInColumn: Array<number> = [];
let unusedDigitsInRow: Array<number> = [];
let unusedDigitsInColumn: Array<number> = [];
let unusedDigits: Array<number>;
let randomDigitFromUnused: number;
digitsExistingInRow = row.map(square => square.digit);
unusedDigitsInRow = possibleOptionsForDigit.filter(digit => !digitsExistingInRow.includes(digit));
digitsExistingInColumn = sudoku.filter(square => square.index === columnIndex).map(square => square.digit);
unusedDigitsInColumn = possibleOptionsForDigit.filter(digit => !digitsExistingInColumn.includes(digit));
unusedDigits = unusedDigitsInRow.filter(digit => unusedDigitsInColumn.includes(digit));
randomDigitFromUnused = unusedDigits[generateRandomArrayIndex(unusedDigits)];
return randomDigitFromUnused;
}
function createSudokValues() {
let generatedUnusedDigit: number = 0;
for ( let y = 1; y <= 9; y++ ) {
for ( let columnIndex = 1; columnIndex <= 9; columnIndex++ ) {
while (row.length <= 9) {
console.log('row ', row)
generatedUnusedDigit = unusedDigitInRowAndColumn(sudoku, row, columnIndex);
row.push(
{
digit: generatedUnusedDigit,
index: columnIndex,
shown: true
}
);
break;
}
}
// end of inner loop
// eslint-disable-next-line no-loop-func
setSudoku(prevSquares => [ ...prevSquares, ...row]);
row = [];
// end of outer loop
}
}
useEffect(() => {
console.log('sudoku ', sudoku)
});
useEffect(() => {
createSudokValues();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return (
<div className="App">
<div className="pageContainer">
<p>
Sudoku
</p>
<div className="sudokuContainer">
{
sudoku.map((square, idx) =>
<Square key={idx} {...square}></Square>
)
}
</div>
</div>
</div>
);
}
export default App;
这是打印到屏幕的第一行:
相当于第一行console.logged:
您应该在每次第一个循环运行时初始化行数组,而不是在函数内部使用变量。
所以这个函数:
function createSudokValues() {
let generatedUnusedDigit: number = 0;
for ( let y = 1; y <= 9; y++ ) {
for ( let columnIndex = 1; columnIndex <= 9; columnIndex++ ) {
while (row.length <= 9) {
console.log('row ', row)
generatedUnusedDigit = unusedDigitInRowAndColumn(sudoku, row, columnIndex);
row.push(
{
digit: generatedUnusedDigit,
index: columnIndex,
shown: true
}
);
break;
}
}
// end of inner loop
// eslint-disable-next-line no-loop-func
setSudoku(prevSquares => [ ...prevSquares, ...row]);
row = [];
// end of outer loop
}
}
应该是:
function createSudokValues() {
let generatedUnusedDigit = 0;
let row: Array<SquareType> = [];
let tempSudoku: Array<SquareType> = [];
for (let y = 1; y <= 9; y++) {
for (let columnIndex = 1; columnIndex <= 9; columnIndex++) {
while (row.length <= 9) {
console.log("row ", row);
generatedUnusedDigit = unusedDigitInRowAndColumn(
sudoku,
row,
columnIndex
);
row.push({
digit: generatedUnusedDigit,
index: columnIndex,
shown: true
});
break;
}
tempSudoku.push(...row);
row = [];
}
}
setSudoku(tempSudoku);
}
在循环内设置状态没有什么意义,因为出于性能原因,它会很糟糕,因为状态变量会触发无用的渲染。
并且您还应该删除 App 组件开头的 let row: Array<SquareType> = [];
初始化。