这是一个Codesandbox。
getIDs()
更新cells
,然后需要更新initializeCells()
。但是,此更改不会在分发操作后反映出来。尽管如此,我可以在Redux 开发工具上看到 action 已经通过,并且 的值cells
也相应地发生了变化。gameStart()
正在通过 props 传递给cells
一个子组件,并通过useEffect()
钩子在那里调用。我需要传递一个空数组作为这个钩子的第二个参数,否则它将永远运行,因为每次调用它时状态都会更新。问题是新状态getIDs()
在第一次运行后不适用于以下功能。似乎是gameStart()
完全完成并再次被调用的时候。我需要initializeCells()
在getIDs()
完成后立即更新需要更新的状态。
细胞.js
import React, { useEffect } from "react";
import { useSelector } from "react-redux";
import Cell from "./Container/Container/Cell";
const Cells = props => {
const board = useSelector(state => state.board);
useEffect(() => {
props.gameStart();
}, []);
return (
<div id="cells">
{board.map(cell => {
return (
<Cell
id={cell.id.substring(1)}
key={cell.id.substring(1)}
className="cell"
/>
);
})}
</div>
);
};
export default Cells;
应用程序.js
import React, { useEffect } from "react";
import { useSelector, useDispatch } from "react-redux";
import {
setCells,
setBoard
} from "../../redux/actions/index";
const Game = () => {
const dispatch = useDispatch();
const cells = useSelector(state => state.cells);
const board = useSelector(state => state.board);
const boardSize = useSelector(state => state.boardSize);
async function gameStart() {
await getIDs();
console.log(cells); // []
await initializeCells();
await assignSnake();
await placeFood();
await paintCells();
}
function getIDs() {
let cellID = "";
let collection = [];
for (let i = 1; i <= boardSize.rows; i++) {
for (let j = 1; j <= boardSize.columns; j++) {
cellID = `#cell-${i}-${j}`;
collection.push(cellID);
}
}
dispatch(setCells(collection));
console.log(cells); // []
}
function initializeCells() {
console.log(cells); // []
const board = [];
// for loop never runs because cells is empty
for (let i = 0; i < cells.length; i++) {
board.push(cell(cells[i]));
}
dispatch(setBoard(board));
console.log("Board: ", board); // []
}
function cell(id) {
return {
id: id,
row: id.match("-(.*)-")[1],
column: id.substr(id.lastIndexOf("-") + 1),
hasFood: false,
hasSnake: false
};
}
return (
...
)
}
export default Game;
减速器/ index.js
import {
SET_CELLS,
SET_BOARD
} from "../constants/action-types";
const initialState = {
board: [],
cells: [],
boardSize: {
rows: 25,
columns: 40
}
};
const rootReducer = (state = initialState, action) => {
switch (action.type) {
case SET_CELLS:
return Object.assign({}, state, {
cells: action.payload
});
case SET_BOARD:
return Object.assign({}, state, {
board: action.payload
});
default:
return state;
}
};
动作/ index.js
import {
SET_CELLS,
SET_BOARD
} from "../constants/action-types";
export const setCells = payload => {
return { type: SET_CELLS, payload };
};
export const setBoard = payload => {
return { type: SET_BOARD, payload };
};
常量/动作类型.js
export const SET_CELLS = "SET_CELLS";
export const SET_BOARD = "SET_BOARD";