React useReducer 状态更新了一半

时间:2021-03-24 07:29:40

标签: javascript reactjs reducers

我写了关于游戏的代码,用户必须点击每个单元格不携带地雷(炸弹)
现在我正在努力更新 useReducer
中的状态 太奇怪了
在 Reducer 函数中,我返回了
1.tableData 和 2.opendCount:打开的单元格数量
但只有 tableData 成功返回
opendCount 不返回(使用 react dev 工具检查)

最奇怪的部分是在 return{ blah blah } 代码之前,
opendCount的值非常正常(也用console.log检查) enter image description here 谁能告诉我为什么? 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;

0 个答案:

没有答案