繁体   English   中英

未使用扩展运算符附加数组的 React state

[英]React state for array is not appended using spread operator

我正在使用 React.js 创建数独应用程序。

只有在createSudokValues()的第一个内部循环(仅创建第一行数独)之后,我才遇到将值写入 state sudoku的问题。 外部循环应该生成行的 rest (通过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 中使用变量,您应该在每次第一个循环运行时初始化行数组。

所以这个 function:

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);
  }

在循环内设置状态几乎没有意义,因为出于性能原因它会很糟糕,因为 state 变量会触发无用的渲染。 而且您还应该删除let row: Array<SquareType> = []; 在 App 组件的开头进行初始化。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM