2017-09-27 2 views
0

J'essaie d'accéder à this.refs pour pouvoir faire défiler vers le haut d'une liste non hiérarchique mais ce n'est pas défini.React Native - Comment Accéder Refs?

Mon méthode render est la suivante:

render() { 
    return (
     <View style={styles.container}> 
     { this.state.loading && 
      <ActivityIndicator /> 
     } 
     { !this.state.loading && 
      <FlatList 
      ref='flatList' 
      data={this.state.facebookPosts} 
      onEndReachedThreshold={0} 
      onEndReached={({ distanceFromEnd }) => { 
       this._getFacebookPosts(this.state.nextPost); 
      }} 
      renderItem={({item}) => <FacebookPost 
       date={item.created_time} 
       message={item.message} 
       image={item.attachments.data[0].media.image.src} 
       url={item.link} 
      />} 
      /> 
     } 
     </View> 
    ) 
    } 
} 

Comme vous pouvez le voir, je l'arbitre fixé comme 'flatList'. J'ai alors une barre d'onglets que lorsque vous cliquez sur l'un des onglets, il est destiné à faire défiler vers le haut de la liste. (Je suis en train juste pour ne pas déconnecter les consoler this.refs mais s'Undefined)

static navigationOptions = { 
    tabBarLabel: 'News', 
    showIcon: true, 
    tabBarIcon: ({ tintColor }) => (
     <Image 
     source={require('../assets/images/newspaper-icon.png')} 
     style={[styles.icon, {tintColor: tintColor}]} 
     /> 
    ), 
    tabBarOnPress: (scene, jumpToIndex) => { 
     // this.refs.listRef.scrollToOffset({x: 0, y: 0, animated: true}) 
     console.log(this.refs); 
     jumpToIndex(scene.index); 
    } 
    }; 

Que dois-je faire différemment pour obtenir this.refs de ne pas être non défini dans cette fonction de onTabBarPress?

+0

https://facebook.github.io/react/docs/refs-and -the-dom.html – euvl

+0

@euvl Ouais ça ne m'aide pas. J'ai lu que déjà – Tenatious

+0

cela fonctionne-t-il si vous essayez 'ref = {flatList => this.flatList = flatList}' et utilisez 'this.flatList' dans votre fonction? –

Répondre

1

Dans mon option, vous pouvez seulement accéder aux refs qui sont dans la même classe. Vous faites ce que vous voulez faire mais en utilisant componentDidMount quand il monte vous faites défiler la liste

+0

Les composants ne sont pas démontés lors du changement d'onglet, donc je ne peux pas simplement déclencher quelque chose sur componentDidMount à chaque fois. – Tenatious

+0

@Tenatious utilise un gestionnaire d'état comme Redux ou Mobx? Vous pouvez vérifier l'état de navigation si c'est l'onglet que vous voulez faire défiler sur 'componentWillReceiveProps'. Je ne suis pas vraiment sûr mais le componentDidMount est déclenché à chaque fois que l'onglet se déplace. –

0

Il semble que vous essayez d'accéder à une propriété de l'instance de classe dans une propriété statique qui ne connaît rien à propos de l'instance. Les propriétés statiques sont liées à class et non à l'instance de classe. Par conséquent, leur mot-clé this ne fait pas référence à l'instance de classe.

Il semble que vous utilisez react-navigation et vous pouvez donc pirater l'instance (this) dans votre propriété navigationOptions statique en faisant cela en componentDidMount.

componentDidMount() { 
    this.props.navigation.setParams({ instance: this }); 
} 

Et vous pouvez définir votre navigationOptions en fonction comme celui-ci pour obtenir l'accès à vos params de navigation.

static navigationOptions = ({ navigation }) => ({ 
    tabBarLabel: 'News', 
    showIcon: true, 
    tabBarIcon: ({ tintColor }) => (
    <Image 
     source={require('../assets/images/newspaper-icon.png')} 
     style={[styles.icon, {tintColor: tintColor}]} 
    /> 
), 
    tabBarOnPress: (scene, jumpToIndex) => { 
    navigation.state.params.instance.refs.listRef.scrollToOffset({x: 0, y: 0, animated: true}) 
    jumpToIndex(scene.index); 
    } 
}); 

Cela peut ne pas être la meilleure façon, mais il est une façon pour l'accomplir.

0

Les problèmes dans votre code sont

  1. ref prend une fonction pas une chaîne
  2. scrollToOffset n'utilise pas x, y en tant que paramètres. Si vous voulez faire défiler jusqu'à un certain index, utilisez plutôt scrollToIndex.
  3. bind isLoading avec rafraîchissante est mieux que injectez FlatList après le chargement

Le code ci-dessous devrait fonctionner:

class MyListView extends React.Component { 
    _listRef; 
    ... 

    render() { 
    return (
     <View> 
      <FlatList 
      ref={ref => {this._listRef = ref; }} 
      data={this.state.facebookPosts} 
      renderItem={({item}) => <FacebookPost 
       date={item.created_time} 
       message={item.message} 
       image={item.attachments.data[0].media.image.src} 
       url={item.link} 
      />} 
      ... 
      refreshing={this.state.loading} 
      /> 
     } 
     </View> 
    ) 
    } 

    scrollToIndex = (idx) => { 
    this._listRef.scrollToIndex({ index: idx, animated: true }); 
    } 
}