React 函數被調用兩次而不是一次

古狐

我正在使用 React 創建數獨遊戲應用程序。目前,我正在創建生成數獨方塊的函數(為其行和列中不存在的隨機數創建隨機數)。

問題是從useEffect()生成的數獨方塊中調用該函數並對其進行安慰,它會生成 2 個方塊數組而不是一個。如果我在普通 JS 中運行這些函數而不是 react,一切都會按預期工作,並生成 81 個正方形。

我錯過了什麼?謝謝!

import React, { useEffect } from 'react';
import '../App.css';
import Square from './Square';

function App() {

    type SquareType = {
        id: number;
        digit: number;
        index: number;
        shown: boolean;
    }

    let row: Array<SquareType> = [];
    let previuosRows: Array<SquareType> = [];
    let sudoku: Array<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 idIncremented: number = 0;
        let generatedUnusedDigit: number = 0;
        for ( let y = 1; y <= 9; y++ ) {
            for ( let columnIndex = 1; columnIndex <= 9; columnIndex++ ) {
                while (row.length <= 9) {
                    generatedUnusedDigit = unusedDigitInRowAndColumn(sudoku, row, columnIndex);
                    //console.log("unusedDigitInRowAndColumn ", unusedDigitInRowAndColumn(sudoku, row, columnIndex));
                    row.push(
                        {
                            id: idIncremented,
                            digit: generatedUnusedDigit,
                            index: columnIndex,
                            shown: true
                        }
                    );
                    idIncremented++;
                    break;
                }
            }
            previuosRows = [ ...sudoku];
            sudoku = [ ...previuosRows, ...row ];
            row = [];
        }
        return sudoku;
    }

    useEffect(() => {
        console.log(createSudokValues())
        // eslint-disable-next-line react-hooks/exhaustive-deps
      }, []);
    return (
        <div className="App">
            <div className="pageContainer">
                <p>
                    Sudoku
                </p>
                <div className="sudokuContainer">
                    {
                        createSudokValues().map((square, idx) =>
                        <Square key={idx}></Square>
                        )
                    }
                </div>
            </div>
        </div>
    );
}

export default App;

這些是打印到控制台的方形對象(雖然只應生成 [0 - 99],但會生成包含 [0 - 99] 和 [100 - 161] 項的數組):

在此處輸入圖片說明

維塔利·雷耶茨

@mcanzerini 是的,useEffect您可以createSudokValuessudoku不調用第二次的情況下調用和 jsx 渲染createSudokValues在更新 JSX 時,您必須使用 hook useStateforsudoku重新呈現狀態。然後只需執行sudoku.map()而不是createSudokValues().map(). 例子:

const [sudoku, setSudoku] = useState([]);


function createSudokValues() {
        let idIncremented: number = 0;
        let generatedUnusedDigit: number = 0;
        for ( let y = 1; y <= 9; y++ ) {
            for ( let columnIndex = 1; columnIndex <= 9; columnIndex++ ) {
                while (row.length <= 9) {
                    generatedUnusedDigit = unusedDigitInRowAndColumn(sudoku, row, columnIndex);
                    //console.log("unusedDigitInRowAndColumn ", unusedDigitInRowAndColumn(sudoku, row, columnIndex));
                    row.push(
                    {
                        id: idIncremented,
                        digit: generatedUnusedDigit,
                        index: columnIndex,
                        shown: true
                    }
                );

                    idIncremented++;
                    break;
                }
            }
            setSudoku(prev => { 
               return [ ...prev, ...row]
            });
            row = [];
        }
}

useEffect(() => {
    createSudokValues();
}, []);

JSX:

{
    sudoku.map((square, idx) =>
        <Square key={idx}></Square>
    )
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

做一次,然后在React js中每隔15秒执行一次

React Components中的一次动作

安装React组件后调用一次GraphQL Mutation

如何只在React中一次请求API数据,而不是每次访问都呈现页面?

在React中只运行一次函数

React 组件只更新一次

React onSetstate 函數多次調用

如何檢測遞歸函數的最後一次調用?

有沒有辦法在 Google Apps 腳本中每隔幾秒調用一次函數?

有沒有辦法在 Google Apps 腳本中每隔幾秒調用一次自定義函數?

react useEffect(): Hello 只記錄一次

fetch 函數被調用兩次

React setState 數組在第二次調用時追加兩次相同的項目

如果在 React 的另一個組件中被調用,則檢測函數

函數不僅調用一次

為什麼只有第一次 React 函數組件獲取 props

React 函數被多次調用(每秒)

更簡潔的方式,而不是每秒運行一次函數

如何在 Jetpack Compose 中每 5 秒調用一次函數

在 onPress 之前調用 React Native 函數

為什麼我的代碼調用一個函數兩次?

在 React 中一次 checkBox

為什麼 React 在第一次調用函數時返回空?

React 新手,第一個按鈕有效,第二個按鈕應該調用自己的函數,但似乎調用了第一個函數

React onChange 只工作一次

第一次調用 Julia 函數時如何執行一些代碼?

React Hook "useSelector" 在函數 "posts" 中調用,它既不是 React 函數組件也不是自定義 React Hook 函數

React - 如何將道具傳遞給類函數調用,然後在 componentDidMount 函數中訪問

從 Render 調用函數 - React