42 votes

Dans React.js, dois-je adresser ma demande réseau initiale à ComponentWillMount ou ComponentDidMount?

Dans le réagir docs il recommande de faire initial des demandes de réseau dans l' componentDidMount méthode:

componentDidMount() est appelée immédiatement après un composant est monté. Initialisation qui nécessite des nœuds DOM devrait aller ici. Si vous avez besoin de charger des données à partir d'un point de terminaison distant, c'est un bon endroit pour instancier la demande du réseau. Réglage de l'état dans cette méthode va déclencher un nouveau rendu.

Si componentWillMount est appelé avant le rendu de la composante, n'est-il pas préférable de faire la demande et de définir l'état ici? Si je le fais en componentDidMount, le composant est rendu, la demande est faite, l'état est changé, alors le composant est un nouveau rendu. Pourquoi n'est-il pas préférable de faire la demande avant que quelque chose soit rendue?

105voto

Dan Points 16670

Vous devriez faire des demandes en componentDidMount.

Si componentWillMount est appelé avant le rendu de la composante, n'est-il pas préférable de faire la demande et de définir l'état ici?

Non, parce que la demande n'arrive pas à terminer par le temps, le composant est rendue de toute façon.

Si je le fais dans componentDidMount, le composant est rendu, la demande est faite, l'état est changé, alors le composant est un nouveau rendu. Pourquoi n'est-il pas préférable de faire la demande avant que quelque chose soit rendue?

Parce que tout réseau de requête est asynchrone. Vous ne pouvez pas éviter un second rendu de toute façon, à moins que vous en cache les données (et dans ce cas, vous n'avez pas besoin de feu de la demande à tous). Vous ne pouvez pas éviter un second rendu par la cuisson plus tôt. Il ne va pas aider.

Dans les futures versions de Réagir nous nous attendons à ce que l' componentWillMount le feu plus d'une fois, dans certains cas, de sorte que vous devez utiliser componentDidMount pour les demandes de réseau.

6voto

János Weisz Points 233

Vous devez utiliser componentDidMount.

Pourquoi n'est-il pas préférable de faire la demande avant que quelque chose soit rendue?

Parce que:

  • Votre demande sera presque certainement pas terminée avant que le composant est rendu (à moins que le rendu de grandes quantités de balisage, ou vous êtes sur un zéro latence de l'intrication quantique de connexion), et le composant sera finalement besoin de re-rendre de nouveau, la plupart du temps
  • componentWillMount est également appelée au cours de rendu côté serveur (le cas échéant)

Cependant, si vous demandez, n'est-il pas préférable d' initier une demande en componentWillMount (sans manipulation en place), je serais certainement dire oui (ES6), et je le fais moi-même de temps en temps de couper quelques millisecondes de temps de chargement:

componentWillMount() {
    // if window && window.XMLHttpRequest
    if (!this.requestPromise) {
        this.requestPromise = new Promise(resolve => {
            // ... perform request here, then call resolve() when done.
        });
    }
}

componentDidMount() {
    this.requestPromise.then(data => ...);
}

Cela va démarrer le préchargement votre demande lors de l' componentWillMount, mais la demande n'est traitée en componentDidMount, si c'est déjà fini d'ici là, ou encore en cours.

4voto

Foxhoundn Points 964

Vous devez en faire la demande dans componentDidMount que pas d'effets secondaires les demandes doivent être faites dans componentWillMount. C'est bien d'setState dans componentWillMount, si vous setState dans componentDidMount vous serez immédiatement déclencher une deuxième re-rendre.

Vous verrez que c'est un anti-modèle (UGHHH) et certains linters de l'avoir interdite (eslint-réagir-plugin), mais je ne voudrais pas payer une attention particulière à ce que parfois, c'est la seule façon d'interagir avec les DOM. Vous pouvez définir votre état par défaut soit dans willMount ou comme une propriété de la méthode ( état = { } ), si vous êtes à l'aide de l'associé babel stade

Comme vous le dites, le composant sera rendu, déjà une fois, mais c'est bien parce que vous pouvez afficher une sorte de Chargeur ou de toute autre forme d'information qu'une ressource est en cours de chargement.

class MyComp extends Component {

    // What I do with stage 0
    state = { mystate: 1 }

    // What you might want to do if you're not 
    // on the experimental stage, no need to do 
    // the whole constructor boilerplate
    componentWillMount() {
        this.setState({ mystate: 1 });
    }

    componentDidMount() {
        dispatch(yourAction());

        // It's fine to setState here if you need to access 
        // the rendered DOM, or alternatively you can use the ref
        // functions
    }

    render() {
        if (!this.props.myCollection) return <Loader />

        return (
           <div> // your data are loaded </div>
        )
    }
}

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