我写了关于游戏的代码,用户必须点击每个单元格不携带地雷(炸弹)
现在我正在努力更新 useReducer
中的状态
太奇怪了
在 Reducer 函数中,我返回了
1.tableData 和 2.opendCount:打开的单元格数量
但只有 tableData 成功返回
opendCount 不返回(使用 react dev 工具检查)
最奇怪的部分是在 return{ blah blah } 代码之前,
opendCount的值非常正常(也用console.log检查)
谁能告诉我为什么? TT
我的这个代码的github仓库
https://github.com/summer-kim/React_Study/tree/main/components/findingMine
reducer.js
case ACTION_TYPE.OPEN_CELL: {
const tableData = [...state.tableData];
const mineList = [
TABLE_CODE.MINE,
TABLE_CODE.QUESTION_MINE,
TABLE_CODE.FLAG_MINE,
];
const recursiveLog = [];
console.log('state:' + state.opendCount);
let opendCount = 0;
const checkMines = (rowCurr, colCurr) => {
if (mineList.includes(tableData[rowCurr][colCurr])) {
return;
}
if (tableData[rowCurr][colCurr] >= TABLE_CODE.OPEND) {
return;
}
if (recursiveLog.includes(rowCurr + ' ' + colCurr)) {
return;
} else {
recursiveLog.push(row + ' ' + col);
}
let aroundCell = [
[rowCurr - 1, colCurr - 1],
[rowCurr - 1, colCurr],
[rowCurr - 1, colCurr + 1],
[rowCurr, colCurr - 1],
[rowCurr, colCurr + 1],
[rowCurr + 1, colCurr - 1],
[rowCurr + 1, colCurr],
[rowCurr + 1, colCurr + 1],
];
aroundCell = aroundCell.filter(
(coord) =>
coord[0] > -1 &&
coord[0] < tableData.length &&
coord[1] > -1 &&
coord[1] < tableData[0].length
);
const extractCode = aroundCell.map(
(coord) => tableData[coord[0]][coord[1]]
);
const count = extractCode.filter((code) => mineList.includes(code))
.length;
tableData[rowCurr][colCurr] = count;
if (count === 0) {
//call Recursive function (to open all cell doesn't carry mine)
aroundCell.forEach((coord) => checkMines(coord[0], coord[1]));
}
opendCount++;
};
checkMines(row, col);
console.log('after :' + opendCount);
return {
...state,
opendCount,
tableData,
};
}
<块引用>
MineSearch.js(主)
import React, { useReducer, createContext, useMemo } from 'react';
import reducer from './reducer';
import { TABLE_CODE } from './code';
import Form from './Form';
import Table from './Table';
export const TableContext = createContext({
tableData: [],
dispatch: () => {},
halted: false,
result: 'Win',
opendNum: 0,
});
const initialState = {
opendNum: 0,
tableData: [],
result: 'Win',
halted: false,
};
export const plantMine = ({ rows, cols, mines }) => {
const data = [];
const shuffle = [];
const candidate = Array(rows * cols)
.fill()
.map((v, idx) => idx);
while (shuffle.length < mines) {
const randomNum = Math.floor(Math.random() * candidate.length);
const mineLocation = candidate.splice(randomNum, 1)[0];
shuffle.push(mineLocation);
}
for (let i = 0; i < rows; i++) {
const rowArray = [];
for (let j = 0; j < cols; j++) {
rowArray.push(TABLE_CODE.NORMAL);
}
data.push(rowArray);
}
shuffle.forEach((location) => {
const row = Math.floor(location / cols);
const col = location % cols;
data[row][col] = TABLE_CODE.MINE;
});
return data;
};
const MineSearch = () => {
const [state, dispatch] = useReducer(reducer, initialState);
const { tableData, halted, result, opendNum } = state;
const contextValue = useMemo(
() => ({ tableData, dispatch, halted, result, opendNum }),
[tableData, halted, opendNum]
);
return (
<TableContext.Provider value={contextValue}>
<div className='d-flex flex-row justify-content-center align-items-center'>
<Form />
<Table />
</div>
</TableContext.Provider>
);
};
export default MineSearch;