From 5cfa125b979c7ce76884a81dd3baaddcf4a560fd Mon Sep 17 00:00:00 2001 From: Joe Savona Date: Thu, 24 Aug 2023 17:22:50 -0700 Subject: [PATCH] Relax FlatList.onViewableItemsChanged validation (#39153) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/39153 `FlatList`'s restriction on not changing the `onViewableItemsChanged` prop forces developers to violate the rules of React, risking bugs and blocking the rollout of other improvements such as React Forget. This diff relaxes the validation specifically for the seemingly common case in which a developer passes just a onViewableItemsChanged prop instead of viewabilityConfigCallbackPairs. We use an anonymous closure to create a stable identity that will be passed down to the underlying VirtualizedList, where the closure calls the current `props.onViewableItemsChanged`. The intent of this diff is to alleviate the worst impacts of the current restriction with a correct if not ideal solution, giving us time to fix the API more holistically. Feedback welcome! ## Changelog: [Changed] - Allow passing different values to `FlatList.onViewableItemsChanged` ## Facebook See https://fburl.com/workplace/9svfrytw for more context. Reviewed By: NickGerleman Differential Revision: D48656586 fbshipit-source-id: 5b0926deada25637786c4cf3b329607d9f515528 --- .../react-native/Libraries/Lists/FlatList.js | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/packages/react-native/Libraries/Lists/FlatList.js b/packages/react-native/Libraries/Lists/FlatList.js index 63e2de283821b1..1b2ee1707c10a5 100644 --- a/packages/react-native/Libraries/Lists/FlatList.js +++ b/packages/react-native/Libraries/Lists/FlatList.js @@ -436,7 +436,16 @@ class FlatList extends React.PureComponent, void> { * see the error delete this comment and run Flow. */ viewabilityConfig: this.props.viewabilityConfig, onViewableItemsChanged: this._createOnViewableItemsChanged( - this.props.onViewableItemsChanged, + // NOTE: we use a wrapper function to allow the actual callback to change + // while still keeping the function provided to native to be stable + (...args) => { + invariant( + this.props.onViewableItemsChanged, + 'Changing the nullability of onViewableItemsChanged is not supported. ' + + 'Once a function or null is supplied that cannot be changed.', + ); + return this.props.onViewableItemsChanged(...args); + }, ), }); } @@ -450,8 +459,9 @@ class FlatList extends React.PureComponent, void> { 'changing the number of columns to force a fresh render of the component.', ); invariant( - prevProps.onViewableItemsChanged === this.props.onViewableItemsChanged, - 'Changing onViewableItemsChanged on the fly is not supported', + (prevProps.onViewableItemsChanged == null) === + (this.props.onViewableItemsChanged == null), + 'Changing onViewableItemsChanged nullability on the fly is not supported', ); invariant( !deepDiffer(prevProps.viewabilityConfig, this.props.viewabilityConfig),