diff --git a/Libraries/Lists/ListView/ListView.js b/Libraries/Lists/ListView/ListView.js index b240620b1504c1..9d1443e8fe484e 100644 --- a/Libraries/Lists/ListView/ListView.js +++ b/Libraries/Lists/ListView/ListView.js @@ -18,7 +18,6 @@ const RCTScrollViewManager = require('NativeModules').ScrollViewManager; const ScrollView = require('ScrollView'); const ScrollResponder = require('ScrollResponder'); const StaticRenderer = require('StaticRenderer'); -const TimerMixin = require('react-timer-mixin'); const View = require('View'); const cloneReferencedElement = require('react-clone-referenced-element'); const createReactClass = require('create-react-class'); @@ -216,6 +215,7 @@ type Props = $ReadOnly<{| const ListView = createReactClass({ displayName: 'ListView', + _rafIds: ([]: Array), _childFrames: ([]: Array), _sentEndForContentLength: (null: ?number), _scrollComponent: (null: ?React.ElementRef), @@ -223,7 +223,7 @@ const ListView = createReactClass({ _visibleRows: ({}: Object), scrollProperties: ({}: Object), - mixins: [ScrollResponder.Mixin, TimerMixin], + mixins: [ScrollResponder.Mixin], statics: { DataSource: ListViewDataSource, @@ -347,16 +347,23 @@ const ListView = createReactClass({ contentLength: null, offset: 0, }; + + this._rafIds = []; this._childFrames = []; this._visibleRows = {}; this._prevRenderedRowsCount = 0; this._sentEndForContentLength = null; }, + componentWillUnmount: function() { + this._rafIds.forEach(cancelAnimationFrame); + this._rafIds = []; + }, + componentDidMount: function() { // do this in animation frame until componentDidMount actually runs after // the component is laid out - this.requestAnimationFrame(() => { + this._requestAnimationFrame(() => { this._measureAndUpdateScrollProps(); }); }, @@ -384,7 +391,7 @@ const ListView = createReactClass({ }, componentDidUpdate: function() { - this.requestAnimationFrame(() => { + this._requestAnimationFrame(() => { this._measureAndUpdateScrollProps(); }); }, @@ -535,6 +542,14 @@ const ListView = createReactClass({ * Private methods */ + _requestAnimationFrame: function(fn: () => void): void { + const rafId = requestAnimationFrame(() => { + this._rafIds.splice(this._rafIds.indexOf(rafId)); + fn(); + }); + this._rafIds.push(rafId); + }, + _measureAndUpdateScrollProps: function() { const scrollComponent = this.getScrollResponder(); if (!scrollComponent || !scrollComponent.getInnerViewNode) {