首页 > 解决方案 > 当 SectionList/Flatlist 滚动/渲染项目时 UI 线程似乎被阻塞(React Native)

问题描述

我们在我们的 react native 项目中使用 Sectionlist 和 Flatlist,我们使用 websocket 来接收/更新数据。

每次我们通过 websocket 接收数据时,我们都想更新 Sectionlist/Flatlist 中的一些信息,但是我们有超过 100 行,所以当试图重新渲染 UI 线程的列表似乎被阻塞时。因此,onPress 函数延迟了 3~5 秒。

所以我的问题是:

  1. Flastlist/Sectionlist 在更新时是否会重新渲染整个列表,还是仅重新渲染特定行?(因为我们只更新某些特定行中的一些信息,并不是每一行都有新信息要更新)
  2. 如果它重新渲染整个列表,我怎么能让 Flastlist 或 Sectionlist 只重新渲染那些特定的行?
  3. 如果它只重新渲染特定的行,为什么 UI 似乎仍然被阻塞?我怎样才能防止这种情况?
  4. 或者问题不在于 UI 块?也许还有其他原因导致 onPress 功能延迟?如果是这样,有什么问题,我该如何解决?

    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>
    );
    }
    }        
    

第一次:

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

第二次:

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

比较我收到的两个数据,我只想重新渲染列表的第一行,因为只有第一行数据得到了更新。我怎样才能做到这一点?

标签: javascriptreact-nativereact-native-flatlistreact-native-sectionlist

解决方案


我知道这真的很晚了,但对于那些仍然有这个问题的人,你可以通过将 scrollEventThrottle 属性设置为非常高的值来修复它,比如 1000。我应该注意,这只有在你不需要的情况下才有效onScroll 事件。

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

推荐阅读