Lynn
Lynn

Reputation: 207

When SectionList/Flatlist is scrolling/rendering items UI thread seems blocked (React Native)

We use Sectionlist and Flatlist in our react native project and we use websocket to receive/update data.

Every time we receive data via websocket we want to update some information in our Sectionlist/ Flatlist, but we have more than 100 row so when the list trying to re-render UI thread seems blocked. Therefore, the onPress function delay for 3~5 seconds.

So my questions are:

  1. Does Flastlist/Sectionlist re-render the whole list when it's updating or it only re-render specific rows? (Because we only update some information in some specific rows not every rows have new information to update)
  2. If it re-render the whole list, how I can let Flastlist or Sectionlist only re-render those specific rows?
  3. If it only re-render specific rows, why the UI still seem blocked? How can I prevent this situation?
  4. Or maybe the problem is not about the UI block? Maybe there are some other reasons why the onPress function delay? If so, what are the problems and how can I fix that?

    class RowItem1 extends React.Component{
      constructor(props){
      super(props);
     }
    
    shouldComponentUpdate = (nextProps, nextState) => {
        if (nextProps.item == this.props.item) {
      return false;
    }
     return true;
     };
    
    render=()=>{
     return (
        <View>
            <TouchableWithoutFeedback
                onPress={() => { consle.log(1234) }}
            >
            </TouchableWithoutFeedback>
            <View>
                <Text>{this.props.item.text}</Text>
                <Text>{this.props.item.name}</Text>
            </View>
        </View>
    )
     }
     }     
    
    export default class main extends React.Component {
    
             constructor(props) {
            super(props);
        }
    
    componentWillMount = () => {
    var ws = new WebSocket('ws://123456');
    ws.onmessage = function (evt) {
        let data = JSON.parse(evt.data);
        this.setState({
            A: data.A,
            B: data.B,
            C: data.C
        });
    };
    };
    
    getItemLayout = (data, index) => ({ length: 74, offset: 74 * index, index });
    
    renderA = ({ item, index, section }) => {
       return <RowItem1 item={item}/>      
        }
    
    render() {
    return (
        <View>
            <SectionList
                sections={[
                    {
                        title: "A",
                        data: this.state.A,
                        renderItem: this.renderA,
                    },
                    {
                        title: "B",
                        data: this.state.B,
                        renderItem: this.renderB,
                    },
                    {
                        title: "C",
                        data: this.state.C,
                        renderItem: this.renderC,
                    }
                ]}
                initialNumToRender={10}
                removeClippedSubviews={true}
                getItemLayout={this.getItemLayout}
                keyExtractor={(item, index) => item + index}
                extraData={this.state}
                refreshing={this.state.refreshing}
                onRefresh={this.handleRefresh}
            />
        </View>
    );
    }
    }        
    

The First time:

    data = {A:[{'text': 0, 'name': 'A'},{'text': 0, 'name': 'B'}, {'text': 0, 'name':'C'}]}

The Second time:

    data = {A:[{'text': 3, 'name': 'A'},{'text': 0, 'name': 'B'}, {'text': 0, 'name':'C'}]}

Compare the two data I received, I only want to re-render the first row of the list because there is only the first row of data got updated. How can I do that?

Upvotes: 3

Views: 2086

Answers (1)

camrymps
camrymps

Reputation: 327

I know this is really late, but for those of you still having this issue, you can fix it by setting the scrollEventThrottle property to something really high, like 1000. I should note that this will really only work if you don't need the onScroll event.

<FlatList data={data} renderItem={renderItem} scrollEventThrottle={1000} />

Upvotes: 1

Related Questions