简体   繁体   English

React、Mobx、Firebase 条件渲染

[英]React, Mobx, Firebase conditional rendering

i have a problem with a basic conditional rendering.我有一个基本条件渲染的问题。 basically i have this Store:基本上我有这家商店:

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 ;

I'm trying to render a message if i don't have any product stored on firebase, and the loading... message, if i'm getting the data from firebase, so i'm doing this now:如果我没有在 firebase 上存储任何产品,我正在尝试呈现一条消息,并且正在加载...消息,如果我从 firebase 获取数据,那么我现在正在这样做:

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>  
    )
}

how can i print the message "products not found" if i don't have any data on firebase?如果我没有关于 firebase 的任何数据,如何打印消息“未找到产品”? cause in the beginning i initialize the products observable to an array, then react show the loading message and after that it loads in the data, but then if i remove all the data on firebase of course it show the loading message.因为一开始我将可观察到的产品初始化为数组,然后反应显示加载消息,然后加载数据,但是如果我删除 firebase 上的所有数据,它当然会显示加载消息。

You could just extend your ProductStore with a isLoading field:您可以使用isLoading字段扩展您的ProductStore

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;
  }
}

And use this in conjunction with products.length in your view:并在您的视图中将其与products.length结合使用:

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>  
  );
}

If you use firestore, an alternative is the Firestorter library: https://github.com/IjzerenHein/firestorter , which has 'isLoading', 'isActive' and 'ready' that you can utilise.如果您使用 firestore,另一种选择是 Firestorter 库: https : //github.com/IjzerenHein/firestorter ,其中包含您可以使用的“isLoading”、“isActive”和“ready”。

You probably won't want to re-engineer to do this, but others might find it interesting.您可能不想重新设计来执行此操作,但其他人可能会觉得这很有趣。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM