【问题标题】:Delayed redux dispatch call speeds up UI update延迟的 redux 调度调用加速 UI 更新
【发布时间】:2021-06-06 08:01:56
【问题描述】:

我正在尝试在 ReactJs、Redux 和 TS 中创建一个简单的积木游戏。我想无限地从左到右移动堆栈中的顶行,直到按下 Space 或 Enter 键。首先,当 UI 加载时它工作正常,但在它开始加速 UI 更新后不久就会出现不一致的更新。像这样……

Game Preview

Inconsistent UI updates log

我想在延迟 200 毫秒后每次渲染将位置更新 1 步。

我正在尝试这样做。

useEffect(() => {
    if (play) {
        setTimeout(() => {
            moveStackLine(JSON.parse(JSON.stringify(data)), direction);
        }, 200);
    }
});

moveStackLine 函数:

const moveStackLine = useCallback((_data: GameData, directionCopy: 'left' | 'right') => {
    console.log('_data1', _data);
    let _direction = directionCopy;
    const lastIndexData = _data[_data.length - 1];
    if (_direction === 'right' && lastIndexData[1] < gameWidth) {
        lastIndexData[0] += 1;
        lastIndexData[1] += 1;
    }
    if (_direction === 'left' && lastIndexData[0] > 0) {
        lastIndexData[0] -= 1;
        lastIndexData[1] -= 1;
    }

    if (lastIndexData[1] === gameWidth - 1) {
        _direction = 'left';
    } else if (lastIndexData[0] === 0) {
        _direction = 'right';
    }
    _data.splice(_data.length - 1, 1, lastIndexData);
    dispatch({ type: ACTIONS.CHANGE_ACTIVE_LINE_START_END_POS, payload: _data });

    if (_direction !== directionCopy) {
        dispatch({ type: ACTIONS.CHANGE_DIRECTION, payload: _direction });
    }
}, [dispatch, gameWidth]);

上面的函数改变了我的rootState中数据数组的开始和结束位置。

初始状态:

export const gameState: InitialGameState = {
  currentLine: 0,
  gameWidth: 16,
  gameHeight: 20,
  direction: 'right',
  play: true,
  data: [[2, 5], [0, 3], [4, 7]],
}

data数组中的每个数组代表一条线,以及线的开始和结束位置。

我的渲染逻辑如下所示。

const renderLine = (startEndIndex: Array<number>) => {
    const columns = [];
    for (let j = 0; j < gameWidth; j++) {
        columns.push(
            <div className={cx(styles.ball, { [styles.active]: j >= startEndIndex[0] && j <= startEndIndex[1] })}></div>
        );
    }
    return columns;
}

const renderGame = () => {
    const lines = [];
    for (let i = 0; i < gameHeight; i++) {
        lines.push(
            <div id={i.toString()} className={styles.line}>
                {renderLine(data[i] || [-1, -1])}
            </div>
        )
    }
    return lines;
}

return (
    <>
        <div className={styles.gameContainer}>
            {renderGame()}
        </div>
    </>
)

【问题讨论】:

  • 数据是否代表棋盘上的位置?
  • @van 是的,每个数组都是一行。这些数组中的数字代表线路在板上的开始和结束位置。

标签: javascript reactjs typescript redux react-redux


【解决方案1】:

您在这里直接修改_data,我假设它也是您从 Redux 存储中检索到的对象。这意味着您要在 reducer 之外修改 redux 存储。

这样的事情会导致各种副作用。

您不仅在这样做,而且还在修改 lastIndexData - 这也是 对商店中对象的引用 - 在这里,再次,您正在直接修改商店,而不是用 reducer 更新它。

试试

const moveStackLine = useCallback((data: GameData, directionCopy: 'left' | 'right') => {
// .concat will create a new array reference that you can (flatly) modify as you want
 const _data = data.concat()
// .concat will create a new array reference that you can (flatly) modify as you want
lastIndexData = _data[_data.length - 1].concat(); 

【讨论】:

  • 这并没有解决问题。但我想通了。这是因为方向改变调度调用。无论如何感谢您的帮助!
  • 即使没有,这些都是明显的错误 - 留意未来的意外状态突变,也许看看官方的 Redux Toolkit,它会警告你这些。
猜你喜欢
  • 2021-11-14
  • 2020-04-08
  • 1970-01-01
  • 2021-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-29
相关资源
最近更新 更多