除非已触摸,否则用户界面已呈现但屏幕未绘制

时间:2019-03-04 23:37:13

标签: react-native

我们能够确认组件的render()方法正在被调用。我们还看到需要显示的数据已通过props正确传递。但是,实际的手机显示屏只有在触摸到更新后的UI后,才会重新绘制。

有趣的是,这仅发生在生产版本中,而不是应用程序的开发版本中。叹气。

过去,我们是从InteractionManager.runAfterInteractions完成更新时看到的,但是在这种情况下,我们删除了对runAfterInteractions的所有使用,并且仍然看到这种行为。

使用react native 0.57,但在0.58上也遇到相同的问题。

如果需要,我可以提供更多详细信息,但我想知道是否有人以前见过这样的东西,以及他们为解决该问题做了什么。

2 个答案:

答案 0 :(得分:0)

当应该重新粉刷的内容在“ ScrollView”内部时,我也遇到了这个问题。我使用“ FlatList”而不是“ ScrollView”重构了代码,问题消失了。

答案 1 :(得分:0)

这是一场挣扎,但我知道发生了什么事。

TL; DR

解决方案是,每当您通过传递给setTimeout(..., 0)的函数或Realm回调进行UI更新时,将redux操作分派包装在runAfterInteractions中。

一些快速背景:

我在redux回调中调度了Realm操作。该操作反过来将导致UI重新呈现,除非呈现的UI在触摸到屏幕之前不会重新绘制在屏幕上。

当您从传递给InteractionManager.runAfterInteractions的回调中调度redux操作时,观察到类似的行为。这是有道理的,因为传递给runAfterInteractions的回调等待UI完成其工作,然后返回executed as a setImmediate batch。这些回调旨在用于繁重的后台作业,否则将阻止UI渲染。因此,如果要在此类回调中进行UI渲染,则它们本身将像后台工作一样停止工作!

解决方案:

领域回调的要点是通知您某些数据已更改,以便您可以重新呈现UI。但是,领域回调的行为就像传递给runAfterInteractions的回调一样,因此UI重新呈现受到阻碍。我信心十足,决定将Redux操作调度代码移至另一个队列setTimeout。修复程序如下所示:

... 
// assume this is in a callback passed to runAfterInteractions
// or in a realm callback

      // PUT YOUR REDUX ACTION DISPATCHES IN A setTimeout
      // callback
      setTimeout(() => {
        getFilteredCartAreas(dispatch, realm)
        dispatch(new ActionCartAreaCardChanged())
      }, 0)

...

解决方法是在传递给setTimeout的回调中执行UI渲染逻辑。注意零延迟;目标是将逻辑简单地移到UI交互无法阻止的其他队列中。