FlatList ScrollView Error on any State Change - Invariant Violation: Changing onViewableItemsChanged on the fly is not supported

吃可爱长大的小学妹 提交于 2020-04-10 03:28:25

问题


onViewableItemsChanged does not seem to work when there is a state change in the app. Is this correct?

Seems like it wouldn't be very useful if this were the case....

Otherwise, users will be forced to us onScroll in order to determine position or something similar...

Steps to Reproduce

  1. Please refer to snack
  2. Repo has also been uploaded at github
  3. Any state change produces an error when using onViewableItemsChanged
  4. What does this error even mean?

Note: Placing the onViewableItemsChanged function in a const outside the render method also does not assist...

       <FlatList
                data={this.state.cardData}
                horizontal={true}
                pagingEnabled={true}
                showsHorizontalScrollIndicator={false}
                onViewableItemsChanged={(info) =>console.log(info)}
                viewabilityConfig={{viewAreaCoveragePercentThreshold: 50}}
                renderItem={({item}) =>
                    <View style={{width: width, borderColor: 'white', borderWidth: 20,}}>
                        <Text>Dogs and Cats</Text>
                    </View>
                }
            />

Actual Behavior

Error

image


回答1:


Based on @woodpav comment. Using functional components and Hooks. Assign both viewabilityConfig and onViewableItemsChanged to refs and use those. Something like below:

  const onViewRef = React.useRef((viewableItems)=> {
      console.log(viewableItems)
      // Use viewable items in state or as intended
  })
  const viewConfigRef = React.useRef({ viewAreaCoveragePercentThreshold: 50 })


<FlatList
      horizontal={true}
      onViewableItemsChanged={onViewRef.current}
      data={Object.keys(cards)}
      keyExtractor={(_, index) => index.toString()}
      viewabilityConfig={viewConfigRef.current}
      renderItem={({ item, index }) => { ... }}
/>



回答2:


You must pass in a function to onViewableItemsChanged that is bound in the constructor of the component and you must set viewabilityConfig as a constant outside of the Flatlist.

Example:

class YourComponent extends Component {

    constructor() {
        super()
        this.onViewableItemsChanged.bind(this)
    }

    onViewableItemsChanged({viewableItems, changed}) {
        console.log('viewableItems', viewableItems)
        console.log('changed', changed)
    }

    viewabilityConfig = {viewAreaCoveragePercentThreshold: 50}

    render() {
        return(
          <FlatList
            data={this.state.cardData}
            horizontal={true}
            pagingEnabled={true}
            showsHorizontalScrollIndicator={false}
            onViewableItemsChanged={this.onViewableItemsChanged}
            viewabilityConfig={this.viewabilityConfig}
            renderItem={({item}) =>
                <View style={{width: width, borderColor: 'white', borderWidth: 20,}}>
                    <Text>Dogs and Cats</Text>
                 </View>}
          />
        )
    }
}



回答3:


Move the viewabilityConfig object to the constructor.

constructor() {
    this.viewabilityConfig = {
        viewAreaCoveragePercentThreshold: 50
    };
}

render() {
     return(
        <FlatList
            data={this.state.cardData}
            horizontal={true}
            pagingEnabled={true}
            showsHorizontalScrollIndicator={false}
            onViewableItemsChanged={(info) =>console.log(info)}
            viewabilityConfig={this.viewabilityConfig}
            renderItem={({item}) =>
                <View style={{width: width, borderColor: 'white', borderWidth: 20,}}>
                    <Text>Dogs and Cats</Text>
                </View>
            }
        />
    )
}



回答4:


Sombody suggest to use extraData property of Flatlist to let Flatlist notice, that something changed.

But this didn't work for me, here is what work for me:

Use key={this.state.orientation} while orientation e.g is "portrait" or "landscape"... it can be everything you want, but it had to change, if the orientation changed. If Flatlist notice that the key-property is changed, it rerenders.

works for react-native 0.56




回答5:


Remove your viewabilityConfig prop to a const value outside the render functions as well as your onViewableItemsChanged function



来源:https://stackoverflow.com/questions/48045696/flatlist-scrollview-error-on-any-state-change-invariant-violation-changing-on

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!