2017-10-15 16 views
2

Dans un projet React.js, j'obtiens des svgs dans la méthode componentWillMount() lifecycle via une fonction appelée loadAllAssets(). Ceux-ci sont ensuite sauvegardés dans le localStorage de l'utilisateur.Réagir: attendre que tous les actifs soient chargés

(1) Existe-t-il un moyen plus élégant de vérifier si tous les fichiers svg demandés ont bien été sauvegardés dans localStorage autre que d'itérer sur le nombre de requêtes effectuées et de les comparer au contenu de localStorage?

(2) Existe-t-il une meilleure façon d'empêcher l'initialisation de componentDidMount tant que les ressources continuent de se charger, à part d'encapsuler tout le code dans un conditionnel? J'utilise Redux pour que cela me vienne à l'esprit, mais il me semble que j'utilise un marteau pour casser un écrou.

index.js

import { loadAllAssets } from './utils/loadAllAssets'; 

class AppContainer extends React.Component { 
    componentWillMount() { 
    loadAllAssets(); 
    } 
//... 
} 
ReactDOM.render(<Provider store={store} ><AppContainer /></Provider>, 
document.getElementById('root')); 

loadAllAssets.js

import { ajaxSVG } from './gfAssetsLoader'; 

export const loadAllAssets =() => { 
    /* write to localStorage */ 
    ajaxSVG('closeScene', '/assets/svg/close-scene-ani.svg'); 
//... 
} 

gfAssetsLoader.js

export const ajaxSVG = (assetName, path) => { 
    try { 
    let request = new XMLHttpRequest(); 
    request.open("GET", path, true); 
    request.onload = function (e) { 
     if(request.status >= 200 && request.status < 400) { 
     let data = request.responseText; 
     localStorage.setItem(assetName, data); 
     } else console.log('Bad request. request status: ' + request.status); 
    } 
    request.send(); 
    } 
    catch (e) { 
    console.log(e); 
    } 
}; 
+0

les requêtes ajax ne devraient-elles pas être effectuées dans componentDidMount? –

+1

pourquoi ne pas utiliser des promesses? Avant de rendre le conteneur de l'application, pourquoi ne pas charger les images svg d'abord, puis seulement après que la chaîne de promesses a été complétée? Rendez-vous l'application – Maru

Répondre

1

1-

export const loadAllAssets =() => { 
    /* write to localStorage */ 
    return ajaxSVG('closeScene', '/assets/svg/close-scene-ani.svg'); 
    //... 
} 

export const ajaxSVG = (assetName, path) => { 
    return new Promise((resolve, reject) => { 
    try { 
     let request = new XMLHttpRequest(); 
     request.open("GET", path, true); 
     request.onload = function (e) { 
     if(request.status >= 200 && request.status < 400) { 
      let data = request.responseText; 
      localStorage.setItem(assetName, data); 
      resolve(); 
     } else reject('Bad request. request status: ' + request.status); 
     } 
     request.send(); 
    } 
    catch (e) { 
     reject(e); 
    } 
    }); 
}; 

Vous pouvez maintenant concaténer un .then à loadAllAssets() et en changer l'état. 2- Pour afficher l'état de chargement, il suffit de créer un état de chargement et de le remplacer par false lorsque les données sont chargées. Ainsi, il affichera un chargeur pendant le chargement des données et une fois les données affichées.

import { loadAllAssets } from './utils/loadAllAssets'; 

class AppContainer extends React.Component { 
    constructor() { 
    super(); 

    this.state = { 
     loading: false 
    }; 
    } 

    componentWillMount() { 
    loadAllAssets() 
    .then(() => { 
     this.setState({ loading: false }); 
    }); 
    } 
//... 
    render() { 
    if (this.state.loading) { 
     return (
     <div><h1>Loading...</h1></div> 
     ); 
    } 

    return (
     //...something else 
    ); 
    } 
} 
ReactDOM.render(<Provider store={store} ><AppContainer /></Provider>, 
document.getElementById('root')); 
+0

Vous pouvez également utiliser redux-thunk (ou toute bibliothèque équivalente) si vous ne voulez pas gérer le chargement à l'intérieur de l'état du composant. –

+0

oui, vous pouvez également créer un état à l'intérieur du magasin redux et envoyer une action lorsque l'appel ajax se termine. De cette façon, vous pouvez réutiliser l'état de chargement du magasin Redux dans tous vos composants. –

+0

Awesome! Exactement ce que je cherchais. – gnzg