The problem
Flatlist(VirtualizedList) has problem specific conditions in Web
This list rendered the wrong range of index items, Sometimes It is rendered again constantly
How to reproduce
Simplified test case: https://snack.expo.io/@kunhee_lee/kunhee_lee_test
Steps to reproduce:
Expected behavior
react-native-web/packages/react-native-web/src/vendor/reactnative/VirtualizeUtils/VirtualizeUtils.js
...
const leadFactor = 0.5; // Math.max(0, Math.min(1, velocity / 25 + 0.5));
const fillPreference =
velocity > 1 ? 'after' : velocity < -1 ? 'before' : 'none';
const overscanBegin = Math.max(0,visibleBegin - (1 - leadFactor) * overscanLength, );
const overscanEnd = Math.max(0, visibleEnd + leadFactor * overscanLength);
const lastItemOffset = getFrameMetricsApprox(itemCount - 1).offset;
if (lastItemOffset < overscanBegin) {
// Entire list is before our overscan window
return {
first: Math.max(0, itemCount - 1 - maxToRenderPerBatch),
last: itemCount - 1,
};
}
...
leadFactor(0.5) is not suitable value with some conditions
this makes the overscanBegin value bigger than 0
so It cause the wrong retern with wrong first, last
If you fix this value leadFactor, this matter would is solved
I have tried to make correct formula for leadFactor
Environment (include versions). Did this work in previous versions?
Probably a duplicate of this: https://github.com/necolas/react-native-web/issues/1254
I solved this problem as follows
"react-native-web": "^0.13.9",
node_modules/react-native-web/dist/vendor/react-native/VirtualizedList/index.js
Added a second object on line 349
_this._scrollMetrics2 = {
contentLength: 0,
dOffset: 0,
dt: 10,
offset: 0,
timestamp: 0,
velocity: 0,
visibleLength: 0
};
in line 508 add
_this._scrollMetrics = {
contentLength: contentLength,
timestamp: timestamp,
velocity: velocity,
visibleLength: visibleLength
};
_this._scrollMetrics2 = {
contentLength: contentLength,
dt: dt,
dOffset: dOffset,
offset: offset,
timestamp: timestamp,
velocity: velocity,
visibleLength: visibleLength
};
and line 1265
var _this$_scrollMetrics2 = this._scrollMetrics2,
and line 1278
this._sentEndForContentLength = this._scrollMetrics2.contentLength;
@azesmway This looks promising, but isn't working for me. I'm not sure that I'm implementing properly. Would you be able to supply a diff for the file?
@awmiklovic Hi! No problem, here's the whole file, you can compare.
"react-native-web": "^0.13.13"
PATH: node_modules/react-native-web/dist/vendor/react-native/VirtualizedList/index.js
Awesome, thank you! Here's the diff in case anyone else needs it:
```diff --git a/node_modules/react-native-web/dist/vendor/react-native/VirtualizedList/index.js b/node_modules/react-native-web/dist/vendor/react-native/VirtualizedList/index.js
index 8659501..da00709 100644
--- a/node_modules/react-native-web/dist/vendor/react-native/VirtualizedList/index.js
+++ b/node_modules/react-native-web/dist/vendor/react-native/VirtualizedList/index.js
@@ -346,6 +346,15 @@ function (_React$PureComponent) {
velocity: 0,
visibleLength: 0
};
_this._scrollMetrics = {
@awmiklovic Did it work for you?
@azesmway Yes, nice work!
Do you think this could solve this issue too? https://github.com/necolas/react-native-web/issues/1254
Here is the sandbox
@Sharcoux I believe so. That looks exactly like the bug I was running into.
You should probably upstream this to react native as the code here is copy-paste from there
Looks like this was originally reported in https://github.com/facebook/react-native/issues/28556 and the React Native team pointed @shine784 to react-native-web to report this. Not sure if they're open to a fix at that level, @necolas.
I reopened that issue. If someone writes a PR for RN that improves compatibility on web without negatively effecting RN, I will help get the review prioritized
Most helpful comment
I reopened that issue. If someone writes a PR for RN that improves compatibility on web without negatively effecting RN, I will help get the review prioritized