James Dunay
James Dunay

Reputation: 2724

Flatlist's children saying "Function components cannot be given refs."

I'm getting an error "Warning: Function components cannot be given refs. Attempts to access this ref will fail" when I attempt to add refs to the children of a Flatlist. However, it only seems to happen when I add the refs to the UserinfoGridComponent and not the View component.

Basically, what I believe is happening, from a bunch of googling, is that the flatlist's children are considered functional components, just as the error says, and as such cant accept refs. (but I'm confused because the child has setState...)

What I really need is just a ref inside the child (UserinfoGridComponent) so that I can scroll the flatlist as needed, from within the UserinfoGridComponent component. Is there a way to get this to work?

Parent:


class HomeScreen extends React.Component {
  displayType = ({ item, index }) => {

    const isBookmarked = (this.state.bookmarks.map(bookmark => bookmark.id).indexOf(item.id) !== -1)

    return (
      <View 
        ref={test => console.log("test ref 2", test)} 
        key={item.id} 
        style={[styles.shadowContainer, style={marginHorizontal: 15, marginBottom:25}]}>
        <UserinfoGridComponent
          ref={test => console.log("test ref 1", test)}
          checked={ isBookmarked }
          images={item.promoImages}
          firstImg={item.promoImages ? (item.promoImages[0] || null) : null}
          secondImg={item.promoImages ? (item.promoImages[1] || null) : null}
          avatar={item.avatar || ''}
          name={item.name || ''}
          mainSkill={User.extractSkill(item.skill)}
          secondarySkill={( item.otherSkills && item.otherSkills.length > 0 ) ? User.extractSkill(item.otherSkills[0]) : ''}
          city={item.location.locality}
          state={item.location.region}
          // key={index}
          index={index}
          user={item}
          onUserInfoPress={() => {
            this.props.navigation.navigate('Profile', { 
              user: item,
              clearAllFilters: this.clearAllFilters });
          }}
          onBookmarkPress={this.onBookmarkPress}
        />
      </View>
    )
  }


render() {

    const { creatorSearch } = this.props.data

    return (
      <View style={{flex:1, backgroundColor: 'white'}}>
        <Animated.View style={{ opacity: this.state.initialOpacityAnimation, flex: 1}}>
          <FlatList
            ref={(list) => { this.listRef = list }}
            contentInset={{top: 0, left: 0, bottom: 150, right: 0}}
            scrollIndicatorInsets={{top: 60, left: 0, bottom: 70, right: 0}}
            data={creatorSearch && this.state.initialContentLoaded ? creatorSearch.items : []}
            onEndReachedThreshold={0.3}
            onEndReached={() => this.scrollEnd()}
            ListHeaderComponent={this.listHeaderText}
            ListEmptyComponent={this.emptyListView}
            extraData={this.state.bookmarks.length}
            renderItem={this.displayType}
            scrollEventThrottle={1}
          />
        </Animated.View>
      </View>
    )
  }
}


Child:

class UserInfoGridComponent extends React.Component {

constructor(props) {
    super(props)


    this.state = { 
      loadedUser: { media: { items: [] }},
      promoImages: this.props.user.promoImages
    }
  }

render() {

    const combinedImages = this.state.loadedUser.media.items.length > 0 ? this.state.loadedUser.media.items : this.state.promoImages

    return (
      <View>
       <FlatList
        ref={ref => console.log("THIS IS A TEST", test)}
        horizontal={true}
        data={combinedImages}
        renderItem={this.imageDisplay}
        style={{padding:imageMargin*2}}
        showsHorizontalScrollIndicator={false}
       />
      </View>
}

Upvotes: 1

Views: 724

Answers (1)

Vinil Prabhu
Vinil Prabhu

Reputation: 1289

reference should be assigned as ref={(ref) => this._flatlist = ref}

and you can access flatlist by using this._flatlist

Upvotes: 1

Related Questions