我在基于React的棋盘游戏界面中有以下情况。
我有一个事件处理程序,当玩家移动时会更新状态:
const move = ... this.setState(function (state, _props) { return this.apply_move(state, move); }); apply_move(state, move) { let board_copy = _.cloneDeep(state.board); // applies the move to board_copy somehow ... return { board: board_copy, }; }
然后,我想先渲染我的动作,然后运行AI为机器人产生动作:在AI计算其动作时,此函数调用需要几秒钟。它实际上是在调用WebAssembly函数。
我在componentDidUpdate
中放置了AI移动请求:
componentDidUpdate(prevProps, prevState) { if (this.state.history.length > prevState.history.length) { if (this.botHasToMove()) { this.getMoveFromBot(); // <--- this runs for 5 seconds } } }
[我希望这会在调用
render
之后运行,因此我将首先看到渲染的动作,然后在AI计算时会有几秒钟的暂停,然后应该渲染AI动作。
但是,问题是,即使我在请求AI的移动之前在控制台中看到render
被调用,但我可以看到状态随我的移动而更新,但是DOM本身未更新
render
时才更新。然后,同时显示了两个动作,我可以在浏览器中看到它们。[我希望每次对render
的调用都应更新DOM(如果发生了某些更改,在我的情况下,它已经进行了更改),但是由于某种原因,DOM更新没有发生。
[如果我没有在componentDidUpdate
中调用对AI的长时间调用,则一切正常,可以看到第一个render
的效果。
有人可以解释为什么会发生这种情况,并告诉我在第一次render
调用中强制更新DOM的正确方法是什么?
我在基于React的棋盘游戏界面中遇到以下情况。我有一个事件处理程序,当玩家移动时会更新状态:const move = ... this.setState(function(state,...
我喜欢您所提出的问题,因为我喜欢这种问题,您实际上在代码方面做得很好,但是您的代码有问题,您实际上提到了长调用或长执行代码,JS在单个代码中运行线程,这意味着所有进程都只在一个通道(线程)中运行,因此,我强烈建议您观看有关JS中事件循环的这两段视频,这是造成问题的原因: