你好,
我有显示部分本地和部分远程数据的列表视图。 本地数据是 ListView.DataSource 的初始数据。 此数据源设置在我的自定义组件的状态中,该组件包装 ListView 并在渲染方法中传递给 ListView。 当接收到远程数据时,新数据源通过 cloneWithRowsAndSections 方法克隆并设置为自定义组件的状态。 问题是只重新渲染已经显示的行,滚动后渲染新行。
是错误还是我应该如何强制呈现 ListView? 使用 react-native 0.5 它可以工作,但在升级到 0.6 后,它的行为如上所述。
+1
遇到完全一样的问题。 用 0.5 工作,但用 0.6 打破。
这应该在 0.7 中修复
我遇到了同样的问题。
cloneWithRows 工作正常。 但 cloneWithRowsandSections 没有。
您是否看到 cloneWithRowsandSections 不适用于 0.7?
此外,您可能想尝试将 initialListSize 设置为更大的数字 - 如果在 0.7 中没有为您解决问题,这可能有助于解决问题。
更大的 initialListSize 没有帮助,0.7 我还没有尝试过,因为供应商依赖。 如果有人不快点,我可能会告诉你 0.7 :)
在 0.6 版中与 cloneWithRows 有同样的问题,在 0.5 中工作。
0.7没试过。 会试一试。 我知道我之前也曾尝试将 initialListSize 设置为更高的数字,但没有帮助。
工作在 0.7
也不适用于 0.7.1
在 0.7.1 版本中与 cloneWithRows 有同样的问题
对我来说,它在 0.7.1 中运行良好。
在 0.8.0 中不起作用。
仍然使用cloneWithRows
而不是cloneWithRowsAndSections
cloneWithRows
对你有用吗 yamill? 在 0.8.0 中不适合我。
@coderdave实际上cloneWithRows
也不适合我。 我的错。
@sahrens @ide @michalraska我的scrollY
道具没有更新。 我基本上是试图将滚动偏移量传递给我的组件,如下所示:
renderRow: function (rowData, sectionID, rowID) {
return (
<Row
key={rowData.id} data={rowData} scrollY={this.state.contentOffset}
/>
)
});
但是修复这条线让我成功地收到了我的组件的scrollY
道具。 我想知道此更改是否解决了所有其他问题?
我把它从:
var shouldUpdateRow = rowCount >= this.state.prevRenderedRowsCount && dataSource.rowShouldUpdate(sectionIdx, rowIdx);
到
var shouldUpdateRow = true;
愚蠢的问题。 这与使用 NavigatorIOS 有什么关系吗? 当列表视图被渲染为 NavigatorIOS 的子视图时,我在渲染、填充等方面遇到了一些问题。
@jaygarcia我不这么认为,因为该示例没有使用 NavigatorIOS。 另外,在我自己的项目中,我使用的是 Navigator 而不是 NavigatorIOS。
+1 对我来说,我目前在使用 Navigator 时遇到了这种行为。 我在 0.11 上,我使用 cloneWithRows。
作为解决方法,我不得不使用@christopherdro的解决方案,但我需要充分滚动它才能呈现我的项目(它们很大)。
有趣的是,解决方法与此错误的解决方法有关: https :
listViewScrollView.scrollWithoutAnimationTo(80);
listViewScrollView.scrollWithoutAnimationTo(-80);
好的,使用上面提到的代码,我在嵌套的 ScrollViews 中遇到了一些奇怪的错误:安装后,触发了一个 onScroll 事件,它重新定位了我在这些视图上的初始滚动偏移量。
仍然是 0.12.0 中的错误。 这是视图层次结构:
与0.11.0上的 @Sidnicious 相同的问题。 自 react-native 的早期版本以来,我的应用程序就遇到了这个问题。 如果我将ListView
移出Navigator
层次结构,一切都会按预期进行。
我在使用0.13.0-rc
时遇到了同样的问题
我在0.13.1
有这个问题,只有这个:
constructor(props) {
super(props);
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {dataSource: ds.cloneWithRows(Array.apply(null, {length: 100}).map(Number.call, Number))};
}
render() {
return (
<ListView
style={{paddingTop: 20, flex: 1}}
dataSource={this.state.dataSource}
renderRow={(rowData) => <Text>{rowData}</Text>}
/>
)
对我来说,这个问题只是在从0.14.2
升级到0.16.0-rc
。 对我有用的修复方法是将 ListView 上的pageSize
道具设置为 3。2 对我不起作用,但 3 效果很好。
¯_(ツ)_/¯
与 0.15.0 相同的问题,尝试了所有技巧,但没有运气。 ios 9.1 iphone 6
@nicklockwood - 你能帮忙吗? 好像还有一些bug。
0.14,同样的问题
链接一个类似的 LisView 问题: https :
链接另一个类似的问题: https :
我在 0.16.0 中看到了这个。 有没有人把这个放在 Product Pains 的雷达上? 这变得非常痛苦。 :/
我已将其发布在Product Pains 上。 如果它仍然影响你可以随意投票。
0.16,同样的问题
问题在 0.17 中仍然存在,在数据源上使用 cloneWithRows。 该列表仅在滚动时呈现项目。
我在 0.17 上看到了同样的问题,但禁用removeClippedSubviews
似乎已经解决了它。
+1
我在 0.17 上看到了同样的问题,但禁用 removeClippedSubviews 似乎已经解决了它。
对我来说,无论是否有removeClippedSubviews
它仍然会在 0.17 中发生。 我注意到的是,我的问题可能与手动设置的 contentOffset 和initialListSize
。 如果偏移量超出为initialListSize
呈现的元素的高度,则在用户滚动之前不会呈现所需的元素。
设置了flexDirection: 'row'
列表似乎也存在问题。 当我删除此属性时,所有项目都会呈现。 如果设置了 List 最初只呈现两个项目。
对于使用 Navigator 时的 removeClippedSubviews 问题。
您可能需要检查https://github.com/machard/react-native-advanced-navigation哪里没有出现问题(可能是因为渲染延迟到视图真正在屏幕上之后)
contentContainerStyle
属性中设置的flexDirection: 'row'
和flexWrap: 'wrap'
也存在问题。 对我有用的解决方法是设置pageSize
。
反应原生版本: 0.19.0
谢谢@jittuu设置 pageSize 道具也为我做了!
将 pageSize 设置为什么?
@gre这取决于您的布局。 如果您的视图按行排列,则 pageSize 应该是每行项目的倍数。 您可以试验确切的值,看看它如何影响性能。
您还应该将 initialListSize 设置得足够大以填满整个屏幕。
您可能会发现此提交中的解释很有用: https :
@jittuu这对我flexWrap
时也遇到了这个错误。
谢谢@jittuu将 pageSize 设置为 2 也解决了我的问题!!
在列表视图上滚动、导航应用程序并返回时仍然遇到问题。
pageSize 没有帮助(我尝试了从 1 到 60 的不同值)。
@gre您是否将 initialListSize 设置得足够大? 有我们可以查看的回购吗?
@jaygarcia @nicklockwood我有一个演示来重现这个错误,repo url: ListNotRender
步:
我确信这个错误相对于 ListView 的 removeClippedSubviews 道具,并且该错误仅在它设置为 true 时发生。
在 RN 0.26.0 上,这仍然发生在我们身上。 这里的情况相同:
removeClippedSubviews={true}
抄送@javache
@javache我在本地手动添加了该行,但没有解决问题。
我也在它上面应用了这个 https://github.com/facebook/react-native/commit/1048e5d3445094393298d4e818ff04c41f4e56a7 但也没有成功。 ;)
在 RN 0.28 之上的单个https://github.com/facebook/react-native/commit/1fcd73f3841d5afbabfa3adecfb7d4036d91a60e提交仍然为我创造了错误。
对此进行一些调查,我想知道ListView 是否仍在后台更新(例如在滚动更新期间),即使它不再可见?
因为,事实上,如果我在视图上滚动,这个错误很容易重现给我,当它仍然以 'gravity' 滚动时进行导航,稍等片刻然后单击返回。 全屏将是白色的,直到我再次滚动。
但这基本上是这个错误发生在我身上的唯一情况。 这是〜每个人都相同的重现场景,还是错误比这更广泛?
这种情况与@janmonschke https://github.com/facebook/react-native/issues/1831#issuecomment -22799032 相差不远。
很难找出这个错误的原因,但这是我的 2 美分:
听起来行在后台呈现_white_。 当使滚动视图再次可见时_(例如返回)_,它们仍然是白色的,并且它们不会更新_(因为它们没有理由更新,它们被缓存)_直到发生新的滚动。
如果 ScrollView 仅在它仍然可见时才呈现其子项( updateClippedSubviews
?),它会修复该错误吗? (如果行在后台未呈现,则它们永远不会再次显示为白色)
@javache 1fcd73f 可以用一两行没有填满整个屏幕来修复案例 ListView。 在这种情况下,即使滚动 ListView 也无法重新显示列表行。
我找到了一种重现错误的简单方法:
ListView将是空白的,行超过一个屏幕,滚动ListView会重新显示,行少于一个屏幕,即使滚动ListView也无法重新显示任何东西。 使用 1fcd73f 滚动 ListView 可以重新显示:)
我们选择的解决方案是在刷新时向前和向后移动 1px 的 scrollTo。 这是一种解决方法,但它在两种情况下都有效。
requestAnimationFrame(() => {
this.listview.scrollTo({y: 1});
});
@JBerendes是的,这个 hack 有效。
这是一个更复杂的解决方法,不会破坏用户的滚动:
class ...YourListAbstraction {
_scrollY = 0;
_lastTimeScrolled = 0;
scrollHackToWorkaroundWhiteBug (amount) { // call at appropriated time, with -1 or 1. if possible alternate so you don't change the actual scroll over calls xD
const { list } = this.refs;
if (!list) return;
if (Date.now() - this._lastTimeScrolled < 500) return; // don't mess with user scroll
list.getScrollResponder().scrollTo({
y: this._scrollY + amount,
});
}
onScroll = ({ nativeEvent }) => { // give onScroll={this.onScroll} to ListView
this._scrollY = nativeEvent.contentOffset.y;
this._lastTimeScrolled = Date.now();
};
}
放入你的 ListView 抽象。 然后你需要在适当的时间调用scrollHackToWorkaroundWhiteBug
。 对我来说,每次我更换屏幕时(在转换之前和之后)。
我认为这与 ListView 的scrollRenderAheadDistance
(因为它在被触摸后呈现未呈现的行)有关,我设法通过将scrollRenderAheadDistance
设置为大于 1800 的值来修复它。 scrollRenderAheadDistance
和呈现的行数之间肯定存在相关性,但它不一致。 我发现它通常呈现如下(尽管有时它会呈现所有行):
| scrollRenderAheadDistance | 呈现的行数 |
| --- | --- |
| 1000 | 2 |
| 1200 | 2-5 |
| 1400 | 5 |
| 1600 | 6 |
| 1800 | 7+ |
我正在渲染一个高度为 80pt 的 ListView。 我已经推导出了一个公式,可以帮助您为 ListView 设置正确的scrollRenderAheadDistance
:
scrollRenderAheadDistance = 680 + (ROW_HEIGHT_IN_PIXELS * INITIAL_PAGE_SIZE_IN_PIXELS)
但是,我不明白680
(或340 * 2
)的意义。
编辑:此解决方案适用于调试但不适用于发布方案(适用于 iOS)...
好的,将removeClippedSubviews
为 false 为我解决了这个问题。
我直到从 0.26 升级到 0.29 才遇到这种情况,所以在 0.27、0.28 或 0.29 中引入了一些东西(我还没有针对 0.27 或 0.28 进行测试,但如果有帮助的话我可以)。
@gnestor它在 0.29 中坏了,检查 #8607 和https://github.com/facebook/react-native/commit/1048e5d3445094393298d4e818ff04c41f4e56a7
@gnestor @nihgwu我很确定这个错误不是最近的回归。 这个问题是一年前创建的,我从 RN 0.13 开始就亲身经历过它,并且总是使用解决方法来“生存” ListView。 不使用removeClippedSubviews
会使大列表滞后。
也许有人试图修复它,或者至少是减少出现错误的情况,但这仍然发生在这个初始问题消息中报告的情况。
@gre但我仍然认为 #8607 是在 0.29 中引入的,进入空白视图真的很麻烦,我只是恢复了https://github.com/facebook/react-native/commit/1048e5d3445094393298d4e818ff04c41f4e56a7的更改,一切正常之前没有关闭removeClippedSubviews
将initialListSize
设置为适当的值并将removeClippedSubviews
为 false 解决我的问题
从 0.28 升级到 0.29 后出现此问题。
removeClippedSubviews={false}
解决了这个问题。
另外,就我而言,我正在更新ListView
上的componentDidUpdate()
ListView
高度。
使用自定义超时将componentDidUpdate()
的高度更新代码与setTimeout
包装起来也有帮助。
我也遇到过这种情况,但它是在一个填充了本地数据的 ListView 上。 我也只在 iOS 和升级到 0.29 后看到过这个。 有问题的 ListView 使用this.state.dataSource.cloneWithRowsAndSections
而componentDidMount
是我加载它的时候。
所以removeClippedSubviews={false}
解决了这个问题。
在我的ListView
组件上设置removeClippedSubviews
对我有用。 在使用默认的Navigator
组件时,我只在0.29
上的Release
方案中遇到了这个问题。
我有同样的问题,我已经设置了 flexDirection: 'row' 和 flexWrap: 'wrap',我在 RN 0.29.2 上。 在其他列表视图上(我没有设置 flexDirection: 'row'),我没有这个问题。
像其他海报所说的快速修复是设置适当的 initialListSize 和 pageSize,但我相信这些会使应用程序的响应性降低,例如,如果您有一些过滤器,这些过滤器只会显示您在列表视图中拥有的项目列表的一部分,在过滤器之间点击会很慢,因为列表视图正在尝试重新渲染整个可见区域。
在其他列表视图上,我通过设置 initialListSize=0 pageSize=1 解决了这个问题。 但是我不能在网格列表视图上(flexDirection:'row' 和 flexWrap:'wrap')。
我在 RN v0.31.0-rc.0 上遇到了这个问题。
添加 removeClippedSubviews={false} 似乎解决了这个问题。
“removeClippedSubviews={false}”似乎不是一个好的解决方案,它会渲染所有行并且存在内存管理问题。 除了“listView.scrollTo”和“removeClippedSubviews”之外,有人有更好的解决方案吗?
这个问题在带有 RN 0.31 的 ios 10 beta 上要糟糕得多:-(
removeClippedSubviews
在 Android 上没有帮助我,不得不从ListView
到ScrollView
。
一个非常巨大的错误。 我也遇到了。
确保每个人都在 Product Pains 上点赞。 它已经相当高了,但还不够高,无法进入某人的收件箱:-(这是链接
在这一点上,我会说这可能与#8607 是同一个问题。 看看我的计划如何解决它。
继续存在于0.33.0
仍然存在于 0.32
我昨天遇到了这个错误,设置removeClippedSubviews = {false}
有效。
+1 0.33
Yee,我,同样的问题! +1
0.33,
编辑:
removeClippedSubviews = {false},也为我解决了这个问题。
+1
你能试试这个补丁https://gist.github.com/majak/b0ee1fb6ca725d2cf810d2f0ab394f2e (来自#8607)并告诉我它是否有助于解决这个问题?
@majak感谢您分享此补丁。 我们只是应用它,现在这个问题消失了(RN 0.34)。
@majak这似乎也为我解决了,干得好!
这发生在 RN34 上,当removeClippedSubviews={true}
在 React Native 0.34 上有这个问题。
问题只发生在我有:
flexDirection: 'row',
flexWrap: 'wrap',
justifyContent: 'center',
在列表视图样式上。
initialListSize={100}
为我修好了
@majak你打算用那个补丁创建一个 PR 吗?
@janmonschke 是的! 按照链接的问题进行更新。
在 React Native 0.36 上有这个问题
我可以确认这发生在 0.36
它在模拟器中完美运行,仅在调试模式下运行,但从不在设备上运行。 该列表从未在设备上运行,尝试了上面推荐的所有内容,甚至将ListView
替换ScrollView
,我在我的 android 设备上看到的只是导航器。 (甚至尝试将列表放在导航器之外)
0.37
我仍然可以在 0.36 上找到这个问题,但感谢您的解决!
我仍然在 0.36.1 看到它
我仍然在 0.36.1 看到它
存在于 0.31
initialListSize={1}
帮我解决
在 React Native 0.38 上有这个问题
renderScrollComponent={(props) => <ScrollView style={flex: 1} /> }
这解决了 0.38 版本中的问题,我不知道它是否也适用于以前的版本。
这个归档了 0.38 版本的问题,我不知道是否适用于早期版本
这个问题存在于 0.36。
无法使用 removeClippedSubviews = {false} 和 initialListSize={8}
1年多过去了,这个issue还是open??
仍然存在于 0.39。 设置removeClippedSubviews = {false}
有效。
“removeClippedSubviews={false}”似乎不是一个好的解决方案,我有一个新的解决方案,它对我有用。 平台 iOS。 RCTView.m 文件
我应该创建一个 PR 吗?
有没有人在RN0.40上测试过,升级到RN0.40后不再遇到这个问题
这个问题存在。
1、显示一个ListView,removeClippedSubViews = true;
2、触摸一行进入下一页;
3、屏幕方向旋转90度;
4、返回ListView界面;
ListView 将是空白的,行超过一个屏幕,滚动 ListView 将重新显示
@endpress我已经按照您的步骤操作了,但在使用 RN0.41RC0 时仍然无法重现它
在 0.38 中有这个问题。
我的解决方法是在 0 和 1 之间更改 ListView 的 paddingTop,因此每次都会刷新 ListView。
您可以尝试更改背景颜色、边框等。如果其他属性有效,请告诉我。
@nihgwu仍然存在于 0.40.0
这是问题
@endpress更改(https://github.com/facebook/react-native/issues/1831#issuecomment-270552011)适用于我的情况,它也可能对 facebook/react-native#8607 有所帮助。
我知道补丁可能还远非完美,但我仍然建议你创建一个 PR。
对我来说,即使设置 initialListSize={0} 也能修复它 rn 0.40.0
@majak这个致命问题有什么好消息吗?
FlatList 仍然是实验性的,所以不能保证它有更少的错误或以向后不兼容的方式改变,但你可以自担风险尝试它。
@sahrens @gre是否可以在FlatList之上构建一个抽象层,提供与旧 ListView 相同的 API,以便我们的旧应用程序代码可以保持不变。
@sahrens FlatList 是用 UITableView 实现的吗?
一旦 FlatList 稳定并且不再是实验性的,我们可能会制作一个与 ListView 具有相同 API 的适配器,或者我们可能会在引擎盖下更换 ListView 的实现。
它不使用 UITableView。 它实际上根本不使用任何新的本机代码,它只是带有我们现有本机/框架原语的 JS - 您可以在此处查看实现: https :
@sahrens谢谢你,它很酷也很有用。
@savanthongvanh将初始大小设置为 0 会在初始加载时呈现 ListView 中的所有项目。 如果您有很多物品,请注意这一点。
也在处理这个 rn 0.41.2。 有人有我可以复制的 FlatLIst 的简单实现,真的希望尽快找到解决方案。
谢谢,
朗
FlatList (andVirtualizedList) 如果你想和他们一起玩,他们就在掌握之中。
对于任何处理此问题的人来说,这是一种现在开始使用 FlatList 的简单方法: https ://hackernoon.com/react-native-new-flatlist-component-30db558c7a5b#.xnp03gd2u
将 initialListSize 设置为适当的值并将 removeClippedSubviews 设置为 false 解决我的问题
谢谢@hoperce , removeClippedSubviews
对我有用, initialListSize
导致断断续续的滚动
我有 RN .42 并且我在这里没有看到任何用于 FlatList 的实验库,所以我被卡住了,直到我可以升级(不是一会儿)这个问题。
您始终可以将 FlatList 代码复制到您的应用程序中,即使您没有使用最新版本的 RN。
我仍然可以使用 FlatList 重现“返回时全视图变白”的错误。 我想知道它是否与 ScrollView 没有更多关系。
短暂变白的问题完全不同,并且是 FlatList 独有的。 我们正在努力减轻它,但这是异步窗口渲染的一个棘手的结果。 此问题所指的错误是在用户滚动之前在初始渲染时没有内容可见,我希望可以使用 FlatList 修复此问题。
我在 ListView(以及 FlatList)中也遇到过这个问题。
我刚刚发现我可以通过在视图的构造函数中将我的数据源重置为 [] 然后将其重置为 setTimeout() 中的项目列表来使列表正确呈现
仅供参考我的列表视图嵌入在 TabNavigator 中的 ReactNavigation StackNavigator 中。
此外,以编程方式触发 1px 滚动的黑客仍然适用于 ListView/FlatList。 但是你需要在正确的生命周期(通常是当你回到屏幕时)调用它。
@gre :您是否有针对 FlatList 问题的重现应用程序? 我想尽快解决这个问题!
@gre ,您有示例代码吗? 你的意思是在 componentWillMount 中包含一个 ListView 的组件吗?
@ericvicenti - 看起来它需要来自 RN 的很多其他代码。 我担心它会从其他地方借用零碎的东西。 我可以把它拉出来。 也许把它扔进一个仓库供其他人使用——这允许吗?
@sahrens抱歉它在我公司的应用程序中,但也许我可以尝试创建一个空白示例来重现它!
@natdm在评论中略高于: https :
我在 SectionList 中遇到了这个问题 - 在我滚动之前,初始渲染时为空白。 @sahrens有修复吗?
@smkhalsa你有明确的
@sahrens看起来设置
如果可以,我将尝试在新的回购中隔离问题并发布。
对我来说也是一样(removeClippedSubviews 绝对是错误的触发因素)。 我们刚刚在我们的应用程序中有一个简单的 repro,在 react-native-tab-view 中有列表。 但是我不知道一个更简单的例子是否会重现它。
在此处查看我的回答的最后 2 段https://github.com/facebook/react-native/issues/1831#issuecomment -228775913
我认为这可能与此有关(只是一个假设):
(1) 列表在背景选项卡中呈现,因为它们“超出边界框” removeClippedSubviews 将假定它们不在这里并且不会呈现任何内容(白色)
(2)当标签进行焦点时,由于该选项卡可能会使用类似于<StaticContainer>
东西,因此没有任何“刷新”,它仍然是白色的
(3) 一旦用户“滚动”,就刷新 removeClippedSubviews 逻辑,该逻辑现在确定列表单元格可见并刷新它们。
感谢领导@gre
RN 0.41.2 仍然存在,android 没问题,只是 ios10,设置 removeClippedSubviews={false} 可以解决这个问题。 我的 listView 很小,所以不是大问题。 tabNavigator(react-navigation) 的 stackNavigator 中的 listView。
render() {
return (
<View style={{ flex: 1, justifyContent:'center'}}>
<ListView
dataSource={this.state.dataSource}
renderRow={this._renderRow.bind(this)}
removeClippedSubviews={false}
/>
</View>
);
}
同样的问题在这里。 除了 removeClippedSubviews={false} 之外,没有什么可添加的,它也为我解决了。
@agentilela感谢您的修复,这里有同样的问题
设置removeClippedSubviews={false}
修复它
这个问题存在于 react-native-maps MapView
,AFAIK 不使用ScrollView
并且与ListView
无关。
问题在 RN44 中仍然发生, initialListSize={200}
确实解决了问题,但我认为这不是一个好的长期解决方案,因为在显示之前需要一些时间来渲染。 在超过 100 行的列表视图中很明显。
ps removeClippedSubViews={false}
没有解决我的问题
removeClippedSubViews={false}
为我工作ListView
。
另外, FlatList
也有同样的问题。
我对 ListView/FlatList 和 react-navigation 有同样的问题。
我已经用 TabNavigator 选项中的lazy: true
和 ListView 中的removeClippedSubViews={false}
修复了它
我还可以确认错误发生在 RN 0.44.0 中:
使用 react-navigation + TabNavigator +(ListView 或 FlatList)时发生。
当您转到选项卡时,它看起来是空的。 只有当您滚动一点时,才会显示列表。
唯一没有发生的选项卡位于 TabNavigator 的 initialRouteName 中
如前所述,将 lazy: true 设置为 on 。 TabNavigator 解决了这个问题。
同样的问题,用 removeClippedSubViews 修复
如重复问题https://github.com/facebook/react-native/issues/14069 中所述
我创建了一个 repo 来重现这个问题https://github.com/jcharlet/react_native_listview_bug如果它有任何帮助的话。
此外,在同一用例中使用“react-native-router-flux”而不是“react-navigation”时也不会发生此问题
TabNavigator 中反应导航的一些问题。 removeClippedSubViews={false} 没有帮助。
对我来说同样的问题。 使用带有 TabNavigator 的 react-navigation 和 StackNavigator 作为相关选项卡中的子项,以及普通的 ListView。 RN 0.44 / Expo 17,removeClippedSubviews 和 lazy 都没有帮助我:-/
removeClippedSubviews 帮助我修复了 IOS 版本,但对于 android 我不得不使用 initialListSize
和
"dependencies": {
"react": "16.0.0-alpha.6",
"react-native": "0.44.2",
"react-navigation": "1.0.0-beta.11"
}
和lazy: true
TabNavigator
的TabNavigatorConfig
的
const AppNavigator = TabNavigator({
HomeTab: {
screen: HomeScreen,
path: '/'
},
PeopleTab: {
screen: PeopleNavigator,
path: '/people',
}
}, {
lazy: true
});
const PeopleList = ({ people }) => {
return (
<FlatList
data={people}
renderItem={({item}) => <Text>{item.name}</Text>}
/>
);
};
升级到
{
“反应原生”:“0.44.2”,
“反应导航”:“1.0.0-beta.11”
}
对我有用,StackNavigator 似乎不需要lazy=true
{
“反应原生”:“0.44.2”,
“反应导航”:“1.0.0-beta.11”
}
懒惰=真
removeClippedSubViews={false}
不起作用
这真的很有趣,我想看看这个 2 年的错误什么时候最终会被关闭。
我升级到 react-native 0.44.2,react-navigation 1.0.0-beta.11,并在有问题的 TabNavigator 上设置了“lazy=true”并修复了它。 也许只是设置 lazy=true 就可以了,但我已经更新了。
@jhalborg我用 FlatList 和 removeClippedSubViews={false} 修复了列表的问题。
我正在使用 react-navigation 并且 removeClippedSubViews 使用以下结构对我有用:
模态堆栈 -> 当前选项卡堆栈 -> 包含多个带有导航堆栈的选项卡
我的问题是缺乏性能,所以我根据状态值创建了 removeClippedSubViews 值,这样我就可以根据屏幕是否正在加载来打开/关闭它。
我有一些列表会在另一个选项卡上重新加载,因此我使用以下内容:
constructor (props) {
super(props)
this.state = { removeClippedSubViews: false }
}
componentDidMount () {
this.setState({ removeClippedSubViews: true })
}
resetData () {
const callback = (newRecords) => {
this.setState({ removeClippedSubViews: true, records: newRecords })
}
this.setState({ removeClippedSubViews: false, records: [] }, () => {
someDataHelper.reloadData(callback)
})
}
render () {
return (
<ListView removeClippedSubViews={this.state. removeClippedSubViews} />
)
}
我希望这对某人有所帮助,因为它一直困扰着我一段时间,但最终成为一个非常简单的解决方案。
看起来这个问题现在可以关闭了,原因如下:
想法?
这不是一个真正的错误吗? 如果是,为什么要关闭问题?
关于原因:
removeClippedSubViews
似乎是一个具有性能成本的黑客攻击,在我看来不是一个合理的解决方法。确认这仍然是 FlatList/SectionList 中的一个活动错误。
还有一些与 FlatList/SectionList 的性能有关的问题,这意味着有些人还不能从 ListView 移动,已经弃用它似乎很奇怪。
可以将我上面发布的内容集成到组件本身中吗?
您在从 ListView 迁移时遇到了哪些问题?
我没有看到 ListView 更好的任何细节。 请注意,如果这对您来说是个问题,您可以增加窗口大小或关闭虚拟化,因为 ListView 不会执行任何操作。
在继续之前,我会等待他们回答您刚刚提出的问题,但这无关紧要,这个问题仍然出现在 FlatList 上,应该保持开放。
仅用于一般社区知识。
我在使用嵌套 ListView 的场景中遇到了这个问题,即在 ListView 行中使用 ListView。 我的解决方案是通过将removeClippedSubviews={false}
应用于嵌套的 ListView 来解决的。
react-native-cli: 2.0.1
react-native: 0.41.2
在运行 iOS 9.x 的 iPad 3/iPad Mini 等旧硬件中,使用 ListView/FlatList/VirtualizedList/WindowedListView(无论什么)在大列表中平滑滚动是不可能的。
注意:我说的是平面列表,没有图像,只有行中的文本组件。
有人可以分享一个包含 7000 条记录的数据集的功能示例,其中滚动平滑且不断断续续,我尝试了所有属性配置,但没有运气 😢
同意 - 我也在清除视野外的单元格以进行内存管理。 遗憾的是,许多应用程序中如此重要的组件在许多用例中都如此缺乏性能。 我将在下周左右深入研究它,看看是否有任何显着的性能提升。
在2017年6月10日,下午3:30 +1000,阿里尔Falduto [email protected] ,写道:
在运行 iOS 9.x 的 iPad 3/iPad Mini 等旧硬件中,使用 ListView/FlatList/VirtualizedList/WindowedListView(无论什么)在大列表中平滑滚动是不可能的。
注意:我说的是平面列表,没有图像,只有行中的文本组件。
有人可以分享一个包含 7000 条记录的数据集的功能示例,其中滚动平滑且不断断续续,我尝试了所有属性配置,但没有运气 😢
—
您收到此消息是因为您发表了评论。
直接回复此邮件,在 GitHub 上查看,或将线程静音。
很棒的@lprhodes ,在这里我分享了一个使用 FlatList 的简单用例,其中包含大约 200 条记录,这个例子在带有 iOS 9 的 iPad 3 上不稳定。
import React, { Component } from 'react';
import {
FlatList,
StyleSheet,
View,
} from 'react-native';
import Expo from 'expo';
import {
Text,
ListItem,
SearchBar,
} from 'react-native-elements';
class Feed extends Component {
loadFeed() {
const {data} = this.props;
const sections = [];
data.forEach((value, index) => {
const sectionName = value.name_line_sp;
const section = sections.find((section) => {
return section.title === sectionName;
});
if (section) {
section.data.push(value);
} else {
sections.push({
title: sectionName,
data: [value]
});
}
});
if (__DEV__) {
console.log('Sections size', sections.length);
}
return sections[0];
}
componentDidMount() {
this.flatListRef.scrollToOffset({
animated: false,
offset: 48
});
}
render() {
const feed = this.loadFeed();
return (
<View style={{flex: 1}}>
<Text h5 style={styles.section_title}>{feed.title} ({feed. data.length})</Text>
<FlatList
style={{flex: 1}}
ref={(list) => { this.flatListRef = list; }}
debug
ListHeaderComponent={() => (
<SearchBar
lightTheme
placeholder='Search...' />
)}
data={feed.data} // ~217 records
keyExtractor={(item) => (
item.code_group
)}
renderItem={({ item }) => {
return (
<ListItem
hideChevron
key={item.code_group}
title={`${item.name_group_sp}`}
subtitle={`${item.price_prod}`}
containerStyle={{ backgroundColor: 'white' }}
/>
);
}}
/>
</View>
)
}
}
import catalog from './data/catalog.json';
class App extends Component {
render() {
const data = catalog;
return (
<View style={styles.container}>
<Text h3 style={styles.title}>Skillcase</Text>
<Feed data={data} />
</View>
);
}
}
const styles = StyleSheet.create({
title: {
margin: 20,
marginBottom: 10,
color: 'white'
},
section_title: {
padding: 20,
color: 'white',
backgroundColor: '#1976D2',
},
container: {
flex: 1,
paddingTop: Expo.Constants.statusBarHeight,
backgroundColor: '#42A5F5',
},
});
Expo.registerRootComponent(App);
或世博uri: exp://8v-xvw.outatime.skillcase.exp.direct :80
谢谢 !!!
您的示例代码有许多不良做法在文档中得到了解决。 例如,您不断地重新创建和重新绑定函数,这对 CPU 来说是一种负担,并导致不必要的列表项重新呈现。 你应该确保你的 ListItem 组件是一个 PureComponent,并确保所有传递给它的 props 保持浅相等以防止不必要的重新渲染。 这对于您的应用程序的其余部分也是一种很好的做法。
这应该有很大帮助,但我不能保证在慢速设备上的完美性能。 网络浏览器等其他应用程序在这些设备上的运行效果如何?
@outaTiME你也不应该在每次渲染时调用 loadFeed
@lprhodes渲染方法只执行一个,顺便说一句,我使用一些最佳实践更新了代码,但在装有 iOS 9 的 iPad 3 上仍然断断续续(在 iPhone 7 中一切顺利),我一直在做错事@sahrens? 谢谢你的建议。
import React, { Component, PureComponent } from 'react';
import {
FlatList,
ListView,
Text,
StyleSheet,
View,
} from 'react-native';
import Expo from 'expo';
import {
ListItem,
SearchBar,
} from 'react-native-elements';
class FeedRow extends PureComponent {
render() {
const item = this.props.data;
return (
<Text>{item.name_group_sp}</Text>
)
}
}
class Feed extends Component {
constructor(props) {
super(props);
this.storeListRef = this.storeListRef.bind(this);
}
loadFeed() {
const {data} = this.props;
const sections = [];
data.forEach((value, index) => {
const sectionName = value.name_line_sp;
const section = sections.find((section) => {
return section.title === sectionName;
});
if (section) {
section.data.push(value);
} else {
sections.push({
title: sectionName,
data: [value]
});
}
});
if (__DEV__) {
console.log('Sections size', sections.length /*, images.length */);
}
return sections[0];
}
componentDidMount() {
this.flatListRef.scrollToOffset({
animated: false,
offset: 48
});
}
renderItem(item) {
return (
<FeedRow data={item.item} />
);
}
keyExtractor(item) {
return item.code_group;
}
listHeaderComponent() {
return (
<SearchBar
lightTheme
placeholder='Buscar...' />
);
}
storeListRef(list) {
this.flatListRef = list;
}
render() {
const feed = this.loadFeed();
return (
<View style={{flex: 1}}>
<Text h5 style={styles.section_title}>{feed.title} ({feed. data.length})</Text>
<FlatList
style={{flex: 1}}
ref={this.storeListRef}
debug
// pagingEnabled
ListHeaderComponent={this.listHeaderComponent}
data={feed.data} // ~217 records
keyExtractor={this.keyExtractor}
renderItem={this.renderItem}
/>
</View>
)
}
}
import catalog from './data/catalog.json';
class App extends Component {
render() {
const data = catalog;
return (
<View style={styles.container}>
<Text h3 style={styles.title}>Skillcase</Text>
<Feed data={data} />
</View>
);
}
}
const styles = StyleSheet.create({
title: {
margin: 20,
marginBottom: 10,
color: 'white'
},
section_title: {
padding: 20,
color: 'white',
backgroundColor: '#1976D2',
},
container: {
flex: 1,
paddingTop: Expo.Constants.statusBarHeight,
backgroundColor: '#42A5F5',
},
});
Expo.registerRootComponent(App);
更好,但设置debug
会减慢很多。 在评估性能时,您还应该确保运行的是优化的生产版本,而不是开发/调试版本。 最后,您仍然在每次渲染时创建一个新的样式对象,并且您可以使用 initialScrollPosition 而不是在 onMount 中调用 scrollToOffset。
@sahrens 是的,没有debug
标志,并且通过优化生产构建运行得更好,断断续续更少,正如我在使用 expo 17 之前所说的,它使用 react-native 0.44,我猜是 react-native 的新版本(0.45 ) 对FlatList
。
顺便说一句,为什么在每次渲染中都会创建样式? 在这种情况下,带有flex
样式的渲染(在Feed
组件中)只执行一次:
App
渲染Feed
渲染FeedRow
渲染与@lprhodes告诉我的关于每次渲染的 loadFeed 非常相似,我知道Feed
渲染只执行一次,这是正确的吗?
当您说initialScrollPosition
您的意思是initialScrollIndex
对吗? 它不像scrollToOffset
那样工作,当Feed
挂载时,我需要隐藏ListHeaderComponent
(高度
这个控制台警告怎么样? 我对 renderItem 使用 PureComponent 对吗?
VirtualizedList: You have a large list that is slow to update - make sure your renderItem function renders components that follow React performance best practices like PureComponent, shouldComponentUpdate, etc. {"dt":85588,"prevDt":1497296394821,"contentLength":10023}
谢谢 !!
该警告是一种已在 master 上修复的错误,但是初始挂载的 85 秒太慢了 - 您应该真正深入研究代码以找出需要这么长时间的原因。 如果你在谷歌上搜索 React 性能,或者在更广泛的 React 社区中寻求帮助,那里有很多资源。
是的,我的意思是initialScrollIndex
。 您需要实现getItemLayout
才能使其工作,这应该占ListHeaderComponent
。
伟大的@sahrens ,我害怕像 iPad 3 或操作系统版本 iOS 9 这样的旧硬件......在较新的设备上测试没有性能问题,我想知道是否还有其他人遇到同样的硬件问题......一段时间我会问社区,看看我是否有更深入的了解,谢谢!!!
嗨,我通过将style={{ backgroundColor: 'white' }}
分配给平面列表来修复
那么@hramos和@sahrens ,对于FlatList 的这个问题,最好的解决方法究竟是什么? 使用react-native-tab-vew
0.44.0
使用 react
@sjmueller不是@sahrens说这已经在master 中修复了吗?
@hramos我刚刚再次回顾了整个主题。 我可能已经错过了,但我没有看到@sahrens提到 FlatList 不可见是固定在 master 上的。 我也没有看到引用这个问题的提交/PR,最后也没有推荐的解决方法来解决这个问题。
我确实看到@yaronlevi建议在react-native-tab-view
或TabNavigator
上设置lazy={true}
TabNavigator
,但这会导致即使在 iPhone 7 plus 上也有延迟。
@knappdev说它在 0.44.2 及更高版本上没有lazy
也能工作,所以我会尝试从 0.44.0 升级,看看我是否成功。
我的解决方法是根据是否正在使用平面列表来打开/关闭 removeClippedSubviews。
constructor (props) {
super(props)
this.state = { removeClippedSubviews: false }
this._disableRemoveClippedSubviews = this._disableRemoveClippedSubviews.bind(this)
this._onViewableItemsChanged = this._onViewableItemsChanged.bind(this)
this._renderItem = this._renderItem.bind(this)
}
_disableRemoveClippedSubviews () {
this.setState({ removeClippedSubviews: false })
}
_onViewableItemsChanged({ viewableItems, changed }) {
if (!this.state.removeClippedSubviews) this.setState({ removeClippedSubviews: true })
if (this._disableRemoveClippedSubviewsTimeout) clearTimeout(this._disableRemoveClippedSubviewsTimeout)
this._disableRemoveClippedSubviewsTimeout = setTimeout(this._disableRemoveClippedSubviews, 3000)
}
render () {
const { removeClippedSubviews } = this.state
return (
<FlatList
renderItem={this._renderItem}
removeClippedSubviews={removeClippedSubviews}
onViewableItemsChanged={this. _onViewableItemsChanged}
/>
)
}
对于 FlatList,removeClippedSubviews 现在默认关闭。
对于慢速设备的问题,您是否尝试过 RNTester 应用程序 FlatListExample?
FlatListExample 的表现如何?
对于 FlatList,removeClippedSubviews 现在默认关闭。
是的 - 这就是我在实际滚动时打开它的原因。 这样我得到的随机抖动更少。
然后我用空的单元替换(远)视野外的单元,以减少比 FlatList 本身所做的更多的内存
所以,最后,即使它的性能成本如此之高,仍然没有办法修复它而不是使用removeClippedSubviews={false}
吗?
对我来说,解决方法是为 ios 模拟器远程禁用调试 js
设置lazy: true
似乎对我有用。 还没有测试性能。
我通过removeClippedSubViews={false}
解决了这个问题
最佳解决方案
适用于所有硬件/模拟器。 removeClippedSubViews={false}
并不总是适用于 iPhone 7。
确保在列表视图中强制移动。
componentDidMount() {
requestAnimationFrame(() => {
// HACK TO RELOAD DATA
this.refs._list.scrollTo({x: 1, y: 0, animated: false})
});
}
参考示例。
<ListView
ref="_list"
dataSource={this.state.dataSource}
renderRow={(data, sectionId, rowId) => <Row
rowId={rowId}
selectedRow={this.state.selectedRow}
onPressRow={this._pressRow.bind(this)}
{...data}/>}
renderSeparator={(sectionId, rowId) => <View key={rowId} style={styles.separator} />}
removeClippedSubViews={false}
initialListSize={SortedBrandList.count}/>
问题是它可能已经安装了
在2017年8月24日,在下午3:44,彼得Suwara [email protected]写道:
解决
适用于所有硬件/模拟器。'''componentDidMount() {
requestAnimationFrame(() => {
// HACK 重新加载数据
this.refs._list.scrollTo({x: 1, y: 0, 动画: false})
});
}''''''
ref="_list"
数据源={this.state.dataSource}
renderRow={(data, sectionId, rowId) => }
renderSeparator={(sectionId, rowId) => }
removeClippedSubViews={false}
initialListSize={SortedBrandList.count}
/>'''—
你收到这个是因为你被提到了。
直接回复此邮件,在 GitHub 上查看,或将线程静音。
我至少在模拟器上解决了这个问题:
<ListView removeClippedSubViews={false} .... />
我的猜测是,当 ListView 当前不在屏幕上时,管理 clippedSubviews 的例程没有正确检查边界。 对于在屏幕外呈现然后在屏幕上移动的任何 ListView 组件,这种情况经常发生。 这不应该是一个很难修复的错误。
我很确定这个函数是问题所在: https :
我的猜测是它测量的坐标空间在某些地方不正确。 现在看着它。
还是没有解决这个问题?
@petersuwara :你提议的工作。 谢谢你。 @MattFoley :什么时候可以下载您的修复程序?
不仅仅针对 FlatList,似乎在 ListView 中加载它也是一个问题。
我通过在设置数据源时使用轻微延迟找到了一种解决方法。
当在 componentWillMount 方法中从远程源加载数据时,将运行以下代码。
似乎工作:
setTimeout(function(){
this.updateDataSource(array,newArray)
},30)
updateDataSource = (comments,dataSource) =>{
this.setState({
allComments:comments,
dataSource: this.state.dataSource.cloneWithRows(dataSource),
isLoading:false
})
}
在稍有延迟期间,您始终可以显示加载屏幕。 它太短了,甚至看不见。
我找到了@nathvarun的工作方法。 组件安装线程和组件的更新数据源线程之间似乎存在一些竞争条件。 如果确实是这种情况,我很困惑为什么会发生这种情况,因为两个线程应该按顺序相互配合。
这发生在已经安装的组件中,例如在 react-navigation 中分配给选项卡但当前更多选择的屏幕 - 所以我不确定对 componentWillMount 的修改如何解决这个问题。
我上面的 PR 似乎已经解决了这个问题,但我没有运气把它合并进去。其他人想加入那个 PR 吗?
@MattFoley是否合并。 我现在正在使用你的代码。 它确实解决了我的问题。
将TabNavigator
react-navigation
的TabNavigator
配置为lazy: true
也有效......但很高兴看到react-native
。
如果您使用的是 SectionList 或 Flatlist,只需使用 ref = {(ref)=> this.sectionList = ref }
并在您的代码中 this.sectionList.recordInteraction() - 应该呈现您的视图
@MattFoley的提议修复已经合并,现在是 0.50 版本的一部分: https :
我刚刚更新,我仍然在<ListView />
上看到这个问题。 难道我做错了什么? 这是我的 package.json:
"dependencies": {
"native-base": "^2.3.1",
"react": "^16.0.0",
"react-native": "^0.50.0-rc.1",
"react-native-linear-gradient": "^2.3.0",
"react-native-modal": "^4.1.0",
"react-native-simple-store": "^1.3.0",
"react-navigation": "^1.0.0-beta.11"
},
我认为ListView
现在已被弃用。 最好尝试使用FlatList
看看发生了什么。
我相信我们仍然在 0.50.3 上看到这一点。 其他人可以确认吗?
我通过切换到 FlatList 解决了这个问题。
2017 年 11 月 17 日星期五上午 8:39 Colin Ramsay通知@github.com
写道:
我相信我们仍然在 0.50.3 上看到这一点。 其他人可以确认吗?
—
您收到此消息是因为您发表了评论。
直接回复本邮件,在GitHub上查看
https://github.com/facebook/react-native/issues/1831#issuecomment-345294840 ,
或静音线程
https://github.com/notifications/unsubscribe-auth/AAZnGZ9oz7uKXx-wz3KFg-FSIzejAfM6ks5s3bavgaJpZM4FP1nt
.
啊,我们已经_使用_FlatList。
这仍然是 0.50.3 的问题。 removeClippedSubviews 似乎没有任何效果。 我们可以重新打开这个吗?
我们在 0.50.3 中仍然存在问题。 请重新打开这个。
很抱歉再次打扰,但我们可以重新打开这个吗? 这是一个紧迫的问题。
使用最新的 Expo React Native SDK 遇到了这个问题。 它只发生在 TabNavigator 中的第三个 ListView 上。 如果我交换第 2 和第 3 页,那么新的第 3 页将受到影响。 不过,在我的情况下,removeClippedSubviews 确实修复了它。
requestAnimationFrame(() => { this.listview.scrollTo({y: 1}); });
为我工作。
使用this.listView.scrollToEnd()
不起作用,所以我必须手动计算列表末尾的坐标,然后传递给scrollTo()
对于 flatlist,这可能是由更新相同的数组引起的。 FlatList 检查数据是否不同。 所以利用不可变数组
removeClippedSubviews={false} 修复了我的案例的错误。
<ListView
data={this.state.mockData}
renderRow={(rowData) => this.renderRow(rowData)}
removeClippedSubviews={false}
/>
@edmengel是对的。 我正在做一个项目并且遇到了完全相同的错误。
滚动前:
滚动后:
React-native-router-flux@^4.0.0-beta.27
用于导航,App.js 返回它。 我的搜索页面包含一个列表视图,它有这个错误。 它位于第三个选项卡上。
<Provider store={store}>
<View style={{flex: 1}}>
<Router hideNavBar={true}>
<Scene key="modal" modal>
{/* Tab Container */}
<Scene key="tabbar" tabs={true} tabBarPosition="bottom" tabBarStyle={{borderTopColor:'black', borderTopWidth:1,backgroundColor:'white'}}>
{/*Tabs */}
<Scene key="NewPage" component={NewPage} title="NewPage" icon={TabIcon} hideNavBar={true} />
<Scene key="NewPage2" component={NewPage2} title="Newpage2" icon={TabIcon} hideNavBar={true} />
<Scene key="SearchPage" component={SearchPage} title="Search" hideNavBar={true} />
</Scene>
</Scene>
</Router>
</View>
</Provider>
当我将搜索页面(包含列表视图)从第三个选项卡更改为第二个选项卡时,列表视图工作正常。
为此找到了一个有效的 Hack。
render() {
setTimeout(() => {
this.sectionList && this.sectionList.recordInteraction();
}, 50);
return (
<SectionList ref={(view) => { this.sectionList = view }} />
)
}
<Flatlist style={{ flex: 1 }}/>
这个技巧对我有用。
0.55.4
与ScrollView
和ListView
。 添加removeClippedSubviews={false}
有效。
不幸的是,在我们的例子中,这不是一个选项,因为它需要避免在 Android 上丢失图像https://github.com/facebook/react-native/issues/13600#issuecomment -315629140
渲染时来回滚动仅在导航后发生,因此看起来像过渡到最初的空白屏幕。
弯曲视图也无济于事。
还有其他建议吗?
我发现它只发生在某些滚动位置之后......
https://streamable.com/l5arv
使用 chrome-devtools 检查视图,我可以看到所有子视图都被剪裁了。
仍然卡住, @hramos请重新打开。
还在为这么简单的功能而烦恼吗? 这就是为什么我们从 React Native 转向直接的 Native 代码。
如果就这么简单,请伸出手来修复它@petersuwara
这个问题已经关闭了一段时间。 如果这对您有影响,_请打开一个新问题_并提供尽可能多的细节。 我正在锁定这个问题,因为这里报告的原始问题已修复,并且不清楚每个后来发表评论的人都面临完全相同的问题。
我们在 Facebook 使用FlatList
_extensively_,内部没有出现此类投诉。 例如,这种类型的问题可能发生在特定的导航库中。 用关于你的问题的更多信息打开一个新问题,有一个清晰的重现步骤列表,或者最好是一个小项目,将有很大帮助。
最有用的评论
我在 0.17 上看到了同样的问题,但禁用
removeClippedSubviews
似乎已经解决了它。