62 votes

liaison react-native onPress avec un argument

Le comportement souhaité est de passer un argument (texte) au gestionnaire onClick à console.log mais il semble que je fasse quelque chose de mal avec la syntaxe.

Si je laisse l'argument comme ci-dessous, cela fonctionne bien :

export default class Nav extends Component {
  componentDidMount() {
    this.props.pickNumber(3);
  }

  onPress() {
    console.log('FOOOBAAR');
  }
  render() {
    return (
      <View>
        <Text>####################</Text>
        <Text>Intro Screen</Text>
        <Text>Number: {this.props.numbers}</Text>
        <TouchableHighlight onPress={this.onPress.bind(this)}>
          <Text>Go to Foo</Text>
        </TouchableHighlight>
      </View>
    );
  }

}

Cependant, si je veux passer un argument au gestionnaire onPress, il se plaint "Impossible de lire la propriété 'bind' d'undefined.

export default class Nav extends Component {
  componentDidMount() {
    this.props.pickNumber(3);
  }

  onPress(txt) {
    console.log(txt);
  }
  render() {
    return (
      <View>
        <Text>####################</Text>
        <Text>Intro Screen</Text>
        <Text>Number: {this.props.numbers}</Text>
        <TouchableHighlight onPress={this.onPress('foo').bind(this)}>
          <Text>Go to Foo</Text>
        </TouchableHighlight>
      </View>
    );
  }

}

Merci

Ajout : Si je le change en :

onPress={this.onPress.bind('foo')}

cela ne fonctionne pas non plus.

0 votes

En passant, techniquement, bind n'est pas du tout nécessaire dans ce cas puisque this n'est pas référencée dans le onPress fonction.

70voto

inga Points 1665

Vous pouvez effectuer la liaison dans le constructeur en utilisant ES6 :

export default class Nav extends Component {
  constructor(props) {
    super(props);

    this.onPress = this.onPress.bind(this);
  }

et ensuite

  onPress(txt) {
    console.log(txt);
  }

  render() {
    return (
      <View>
        <Text>####################</Text>
        <Text>Intro Screen</Text>
        <Text>Number: {this.props.numbers}</Text>
        <TouchableHighlight onPress={() => this.onPress('foo')}>
          <Text>Go to Foo</Text>
        </TouchableHighlight>
      </View>
    );
  }
}

1 votes

L'erreur est supprimée mais la chaîne 'foo' est automatiquement consignée dans le journal de la console sans que je ne clique.

1 votes

Désolé, j'ai mis à jour ma réponse. Vous devez ajouter () => avant this.onPress('foo').

0 votes

C'est tout. Merci. Pourriez-vous m'expliquer pourquoi j'ai dû ajouter une fonction de flèche de graisse à cela ? Merci.

36voto

GulshanZealous Points 391

Vous pouvez éviter de lier la fonction dans le constructeur en la liant à la valeur onPress et en passant l'argument après 'this'. Vous pouvez remanier votre code comme suit,

export default class Nav extends Component {
  componentDidMount() {
    this.props.pickNumber(3);
  }

  onPress(txt) {
    console.log(txt);  // foo
  }
  render() {
    return (
      <View>
        <Text>####################</Text>
        <Text>Intro Screen</Text>
        <Text>Number: {this.props.numbers}</Text>
        <TouchableHighlight onPress={this.onPress.bind(this,'foo')}>
          <Text>Go to Foo</Text>
        </TouchableHighlight>
      </View>
    );
  }

}

Le premier argument est 'this' et tous les autres arguments peuvent être fournis après cela et seront reçus dans le même ordre.

Mise à jour : On peut aussi le faire en utilisant des fermetures.

export default class Nav extends Component {
  componentDidMount() {
    this.props.pickNumber(3);
  }

  onPress = (this, txt) => () => {
    console.log(txt);  // foo
  }

  render() {
    return (
      <View>
        <Text>####################</Text>
        <Text>Intro Screen</Text>
        <Text>Number: {this.props.numbers}</Text>
        <TouchableHighlight onPress={this.onPress(this,'foo')}>
          <Text>Go to Foo</Text>
        </TouchableHighlight>
      </View>
    );
  }

}

0 votes

C'est très pratique, car les fonctions de la flèche de la graisse vont probablement déclencher des réexpositions, car react ne peut pas mettre cela en cache.

1 votes

0 votes

Ceci devrait être la réponse préférée, car elle évite de créer une nouvelle fonction anonyme à chaque pression, comme le fera la réponse la mieux notée...

23voto

TechnoTim Points 41

Vous pouvez aussi le résoudre avec des flèches de graisse :

export default class Nav extends Component {

  handlePress = (text) => {
    console.log(text);
  }

  render() {
    return (
      <View>
        <Text>####################</Text>
        <Text>Intro Screen</Text>
        <Text>Number: {this.props.numbers}</Text>
        <TouchableHighlight onPress={() => this.handlePress('weeeeee')}>
          <Text>Go to Foo</Text>
      </TouchableHighlight>
    </View>
    );
  }
}

1 votes

Cette méthode fonctionne, mais elle est moins efficace. Chaque fois que vous tapez sur cette variable, la fonction doit être créée, puis exécutée. Si vous utilisez la définition de la fonction, puis la liaison, à chaque fois que vous tapez sur la variable, la fonction est seulement appelée et n'est pas créée à chaque fois.

12voto

Binova Gautam Points 71

Vous devriez juste passer une fonction de flèche de graisse avant d'appeler la fonction.

onPress= {()=> this.handlePress(param)}

0 votes

C'est de loin la réponse la plus simple et la plus directe, merci !

1voto

GSK Points 1322

Définissez une fonction et appelez-la en appuyant sur le texte. Si vous itérez sur un tableau, vous pouvez également passer le titre

  selectText = (item) => {
            console.log(item) // will print Text Pressed
            alert(item)
      }
   return(
       <View>
       <Text onPress = {()=>this.selectText("Text Pressed")}>Press for Alert</Text>
       </View>
    }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X