2017-10-21 52 views
0

donc ce qui est plus ou moins le codecondition de course avec l'événement de charge en Javascript

Désolé pour la syntaxe, je dactylographié de mon téléphone

export default class Main extends React.Component { 

    componentDidMount() { 
    axios.get('/user?ID=12345') 
    .then(function (response) { 
    if (response){ 
    document.addEventListener('load',() => {/* remove spinner using jquery */}); 
} else { /* redirect to somewhere else */} 
    }) 
    } 

    render() { 
    return (
     <SomeComponent /> 
    ); 
    } 
} 

je addEventListener avec React parce que je ne pouvais pas trouver un autre moyen de lier l'enlèvement de la roue de chargement à l'événement de chargement. Le problème est qu'il y a une course ici, pour les stations de réseau lentes ou celles de CPU rapides, l'événement de chargement peut être lancé longtemps avant que la requête ne soit résolue, ce qui entraîne le maintien du spinner de chargement.

Existe-t-il un moyen de vérifier si l'événement de chargement a déjà été déclenché?

Si je peux le faire, je serai en mesure de le vérifier après avoir ajouté l'écouteur d'événement et au cas où il a déjà été lancé, je vais supprimer le spinner manuellement.

+0

(qui déclenche la méthode render dans laquelle vous pouvez afficher ou non le spinner). Je vous recommande de lire [Réflexion dans Réagir] (https://reactjs.org/docs/thinking-in-react.html) – 3Dos

+0

setState re-rend le composant, je voudrais l'éviter. Je pense qu'il est beaucoup plus simple de régler l'affichage du spinner de chargement sur aucun. –

+0

Mais ce n'est pas le problème ici –

Répondre

3

Je n'utiliserais pas jquery pour cette tâche (ou pas du tout en réagissant) car vous pouvez le faire de manière plus "réactive".
Vous pouvez stocker les données dans votre state et restituer sous conditions le composant dans votre méthode render lorsque l'état a changé. En passant, vous ne pouvez pas éviter le premier render.

exemple Petit:

const Loader =() => <div>Loading...</div> 
 

 
const MyComponent = ({message}) => <div>{message}</div> 
 

 
class App extends React.Component { 
 
    constructor(props) { 
 
    super(props); 
 
    this.state = { 
 
     message: '' 
 
    }; 
 
    } 
 

 
    componentDidMount(){ 
 
    // mimic async operation 
 
    setTimeout(()=>{ 
 
     this.setState({message: 'Hi there!'}) 
 
    }, 1500); 
 
    } 
 

 
    render() { 
 
    const {message} = this.state; 
 
    return (
 
     <div> 
 
     {message ? <MyComponent message={message} /> : <Loader />} 
 
     </div> 
 
    ); 
 
    } 
 
} 
 

 
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 
 
<div id="root"></div>

Modifier
Comme suivi à votre commentaire:

Mais vous réengendrer la totalité du composant juste changer l'affichage style du preloader e lement, n'est-ce pas?

Pas tout à fait vrai, je pense que vous devriez en savoir plus sur Reconciliation and The Diffing Algorithm et regarder this exemple:

React DOM compare l'élément et ses enfants à la précédente, et applique uniquement les DOM mises à jour nécessaires pour amener le DOM à l'état souhaité . Pourquoi utiliser jQuery avec reagir alors que vous pouvez simplement setState?

+0

Merci beaucoup pour votre réponse. J'ai déjà fait quelque chose de similler. Le problème est que componentDidMount n'est pas synchronisé avec l'événement load et peut être lancé bien avant. Cela provoque la disparition du préchargeur longtemps avant que le chargement ne soit effectué (en particulier lorsque le réseau est rapide et que le processeur est lent). Je dois en quelque sorte être synchronisé avec l'événement de chargement –

+0

Je ne suis pas, vous définissez l'état dans le rappel de la promesse.cela signifie que votre état est vide jusqu'à ce que le callback soit invoqué (cela signifie que le premier rendu devrait afficher le 'Loader') après le rappel définissez l'état d'un re-render et maintenant l'autre composant est retourné au lieu du loader. où est le problème avec ce flux? –

+0

Mais alors vous rendez le rendu complet du composant juste pour changer le style d'affichage de l'élément de préchargement, n'est-ce pas? –