2017-09-26 2 views
1

J'ai un problème avec un rendu conditionnel de base. essentiellement Je possède ce magasin:React, Mobx, rendu conditionnel Firebase

import { ObservableMap, observable, action, computed } from 'mobx'; 
import fb from '../firebase'; 

class ProductStore { 
    @observable products = []; 

    constructor() { 
    fb.products.on('value', (snapshot) => { 
     this.products = []; 
     snapshot.forEach((child) => { 
     this.products.push({ 
      id: child.key, 
      ...child.val() 
     }); 
     }); 
    }); 
    } 

    @action addProduct = (product) => { 
    fb.products.push(product); 
    } 

    @action removeProduct = (product) => { 
    fb.products.child(product.id).set({}); 
    } 

    @computed get totalProducts() { 
    return this.products.length; 
    } 


} 

const store = new ProductStore(); 
export default store ; 

J'essaie de rendre un message si je n'ai pas produit stocké sur firebase, et le chargement ... message, si je reçois les données firebase, donc je fais maintenant:

const ProductList = (props) => { 

    const renderView =() => { 
    if(props.products.length){ 
     return props.products.map((product,index) => <Product key={index} product={product} removeProduct={props.removeProduct}/>); 
    }else{ 
     return <p>Loading...</p> 
    } 
    } 

    return (
     <div className="product-list"> 
     {console.log(props.products)} 
     {renderView()} 
     </div> 
    ) 
} 

comment imprimer le message « produits non trouvés » si je n'ai pas de données sur firebase? Parce qu'au début, j'initialiser les produits observables à un tableau, puis réagir montrent le message de chargement et après cela, il charge dans les données, mais si je supprime toutes les données sur Firebase, bien sûr, il montre le message de chargement.

Répondre

1

Vous pouvez simplement prolonger votre ProductStore avec un champ isLoading:

class ProductStore { 
    @observable products = []; 
    @observable isLoading = true; 

    constructor() { 
    fb.products.on('value', (snapshot) => { 
     const products = []; 

     snapshot.forEach((child) => { 
     products.push({ 
      id: child.key, 
      ...child.val() 
     }); 
     }); 

    this.products.replace(products); 
    this.isLoading = false; 
    }, (error) => { 
     this.isLoading = false; 
    }); 
    } 

    @action addProduct = (product) => { 
    fb.products.push(product); 
    } 

    @action removeProduct = (product) => { 
    fb.products.child(product.id).set({}); 
    } 

    @computed get totalProducts() { 
    return this.products.length; 
    } 
} 

Et utiliser conjointement avec products.length dans votre vue:

const ProductList = ({ isLoading, products }) => { 
    let result; 

    if (isLoading) { 
    result = <p>Loading...</p>; 
    } else if (products.length === 0) { 
    result = <p>Products not found</p>; 
    } else { 
    result = products.map((product, index) => <Product key={index} product={product} removeProduct={props.removeProduct}/>); 
    } 

    return (
    <div className="product-list"> 
     {result} 
    </div> 
); 
} 
+1

Merci homme! demain je vais l'essayer au travail! :) une question, vous utilisez remplacer pour retourner un nouveau tableau à droite? pour le rendre immuable? –

+0

@LucaBaxter Génial! J'utilise la méthode MobX array [** replace **] (https://mobx.js.org/refguide/array.html) afin de remplacer le contenu du tableau, et non écraser la référence de tableau observable avec un tableau ordinaire. Des bugs subtils peuvent être introduits de cette façon. – Tholle