【发布时间】:2019-12-30 03:11:30
【问题描述】:
这是Codesandbox。
getIDs() 更新 cells,然后 initializeCells() 需要它。但是,在调度操作后不会反映此更改。尽管如此,我可以在Redux dev tools 上看到该操作已通过并且cells 的值已相应更改。 gameStart() 通过 props 传递给子组件 cells,并通过 useEffect() 钩子在那里调用。我需要传递一个空数组作为这个钩子的第二个参数,否则它将永远运行,因为每次调用它时状态都会更新。问题是新状态在getIDs() 首次运行后不适用于以下功能。似乎是当gameStart() 完全完成并再次被调用时。我需要在getIDs() 完成后立即更新initializeCells() 的状态。
cells.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;
app.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;
reducers/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;
}
};
actions/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 };
};
constants/action-types.js
export const SET_CELLS = "SET_CELLS";
export const SET_BOARD = "SET_BOARD";
【问题讨论】:
-
看来你需要在组件逻辑中使用
useEffect,使用依赖数组。 -
你能扩展一下吗?我不明白你的意思。
-
当然。现在您正在组件内部定义函数,但是当它们内部的参数发生变化时,需要再次调用这些函数。为了实现这一点,我认为应该使用useEffect。
-
我已经更改了调用函数的组件。它最初是通过
componentDidMount()调用的,现在它使用useEffect()。在此之后,函数被无限调用,所以我必须将一个空数组作为第二个参数传递给useEffect()。然而,这并没有改变任何东西,我仍然遇到同样的问题。 -
能否展开组件,
gameStart在哪里被调用?它在渲染什么?
标签: reactjs redux react-redux