Search code examples
javascriptlistviewreactjsreact-nativereact-native-listview

TouchableOpacity onPress hangs inside ListView


I have this ListView UI that started to run slowly once I added the rowData parameter inside the onPress event handler of TouchableOpacity. Once the TouchableOpacity is pressed, it stays pressed for 15 seconds and then again runs smoothly.

There seems to be some collision, because I use rowData also in the renderRow event handler of ListView three lines above.

Am I right and how to solve this problem?

<ListView
    dataSource={this.state.dataSource}
    keyboardShouldPersistTaps={true}
    renderRow={(rowData) =>
        <TouchableOpacity
            onPress={(rowData) => {
                console.log(rowData);//ON THIS LINE IT HANGS 15s
            }}
        >
            <Text>{rowData}</Text>
        </TouchableOpacity>
    }
    automaticallyAdjustContentInsets={false}
/>

Solution

  • I'd be really interested in the explanation of what makes this such an expensive operation in javascript, but the problem is that you're passing rowData as an argument to your onPress function, when rowData is already declared in the upper scope (renderRow). So yes, just like you said, there's a collision.

    Effectively, the value of rowData is being redefined by onPress, since the onPress function receives the touch event as an argument. (You'll notice that the data being logged isn't actually your original row data, but a touch event object).

    You can fix this by simply renaming the first argument of your onPress function. e.g.

     <TouchableOpacity
           onPress={(evt) => {
             console.log(rowData); //now it doesn't hang
           }}
     >