有一个棋盘游戏,每当用户更改其中一个方块的内容时,就会影响所有其他方块的状态。要更改一个正方形的状态,我使用useReducer
,要处理其他正方形的更改,我使用useEffect
。
问题是当用户请求计算机自行解决这种情况时(有这样一个选项(。我的首选解决方案是触发一个递归函数(resolveBoard
(,该函数遍历所有的平方并逐个更改它们。在每个方块中做什么的计算是基于前一个决定在前一个方块中的副作用(上面提到的useEffect
应该做什么(。不幸的是,useReducer
的调度器(以及useEffect
(只有在递归函数完成后才能被调用,这会破坏计算并导致返回错误的结果。
如何做到这一点?
const [squaresValues, dispatchSquaresValue] = useReducer(
setSquaresValue,
{ rows: props.rows, columns: props.columns },
InilizeBoard
);
useEffect(() => {
calculateValues();
}, [squaresValues]);
function resolveBoard(row, index) {
...
if (resolveSingleSquare(row, index)) {
const nextIndex = ...
const nextRow = ....
return resolveBoard(nextRow, nextIndex);
}
return false;
}
function resolveSingleSquare(row, index) {
...calculations based on the state of the others squares
if (working) {
dispatchSquaresValue(squareProp);
return true;
}
return false;
}
function setSquaresValue(prevValues, squareProp) {
--- be called only after all finished:(
}
Ciao,为了在重新调用resolveBoard(nextRow, nextIndex);
之前调度dispatchSquaresValue
,您必须使用Promise机制。所以您不能使用useReducer
。有几种方法可以解决你的问题,我用了2:
-
还原承诺:
export const updateSquareValue = (key, value)=> Promise.resolve({ type:'UPDATE_SQUARE_VALUE', key, value })
然后在您的组件中:
import { useDispatch } from 'react-redux';
...
const dispatch = useDispatch();
...
function resolveBoard(row, index) {
...
dispatch(updateSquareValue(squareProp)).then(() => {
resolveBoard(nextRow, nextIndex);
});
}
还原thunk:
export const updateSquareValue = (key, value) => dispatch => { dispatch({ type: 'UPDATE_SQUARE_VALUE', key, value, }); return Promise.resolve(); };
然后在您的组件中:
import { useDispatch } from 'react-redux';
...
const dispatch = useDispatch();
...
function resolveBoard(row, index) {
...
dispatch(updateSquareValue(squareProp)).then(() => {
resolveBoard(nextRow, nextIndex);
});
}