web-dev-qa-db-fra.com

Pourquoi this.state n'est pas défini dans React Native?

Je suis un débutant complet en réactif natif, react.js et javascript. Je suis Android développeur, je voudrais donc essayer RN.

Fondamentalement, la différence est dans onPress;

Ce code affiche 'undefined' Lorsque toggle () s'exécute:

class LoaderBtn extends Component {
    constructor(props) {
        super(props);
        this.state = { loading: false };
    }

    toggle() {
        console.log(this.state);
        // let state = this.state.loading;
        console.log("Clicked!")
        // this.setState({ loading: !state })
    }

    render() {
        return (
            <Button style={{ backgroundColor: '#468938' }} onPress={this.toggle}>
                <Text>{this.props.text}</Text>
            </Button>
        );
    }
}

mais ce code fonctionne:

class LoaderBtn extends Component {
    constructor(props) {
        super(props);
        this.state = { loading: false };
    }

    toggle() {
        console.log(this.state);
        // let state = this.state.loading;
        console.log("Clicked!")
        // this.setState({ loading: !state })
    }

    render() {
        return (
            <Button style={{ backgroundColor: '#468938' }} onPress={() => {this.toggle()}}>
                <Text>{this.props.text}</Text>
            </Button>
        );
    }
}

Pouvez-vous m'expliquer la différence, s'il vous plaît?

Dans Java/Kotlin nous avons des références de méthode, fondamentalement, il passe la fonction si les signatures sont les mêmes, comme onPress = () => {} et toggle = () => {}

Mais dans JS cela ne fonctionne pas :(

17
Nikita Kraev

Le problème que dans le premier exemple toggle() n'est pas lié à la bonne this.

Vous pouvez soit le lier dans le ctor:

constructor(props) {
    super(props);
    this.toggle = this.toggle.bind(this);
    ...

Ou utilisez une fonction d'instance (OK dans certaines circonstances):

toggle = () => {
    ...
}

Cette approche nécessite des modifications de build via stage-2 ou transform-class-properties.

La mise en garde avec les fonctions de propriété d'instance est qu'il existe une fonction créée par composant. Ce n'est pas grave s'il n'y en a pas beaucoup sur la page, mais c'est quelque chose à garder à l'esprit. Certaines bibliothèques de simulation ne traitent pas non plus particulièrement bien les fonctions de flèche (c'est-à-dire que les fonctions de flèche ne sont pas sur le prototype, mais sur l'instance).

C'est JS de base; cet article concernant React Binding Patterns peut aider.

26
Dave Newton

Je pense que ce qui se passe est une question de portée. Lorsque vous utilisez onPress={this.toggle}, Ce n'est pas ce que vous attendez de votre fonction bascule. Cependant, les fonctions fléchées présentent un comportement différent et se lient automatiquement à this. Vous pouvez également utiliser onPress={this.toggle.bind(this)}.

Lectures complémentaires -

Fonctions fléchées ES6

. bind ()

5
larz

Ce qui se passe dans ce premier exemple, c'est que vous avez perdu la portée de "ceci". Généralement ce que je fais est de définir toutes mes fonctions dans le constructeur comme ceci:

constructor(props) {
    super(props);
    this.state = { loading: false };
    this.toggle = this.toggle.bind(this);
}

Dans le deuxième exemple, vous utilisez la syntaxe ES6 qui la liera automatiquement (c'est pourquoi cela fonctionne).

Ensuite, à l'intérieur de votre fonction onPress, vous devez appeler la fonction que vous avez créée. Donc, cela ressemblerait à quelque chose comme ça,

onPress={this.toggle}
5
Mark Miller