Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/css/42.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript React.js error,Uncaught(in promise)error:元素可能未呈现给DOM_Javascript_Css_Reactjs - Fatal编程技术网

Javascript React.js error,Uncaught(in promise)error:元素可能未呈现给DOM

Javascript React.js error,Uncaught(in promise)error:元素可能未呈现给DOM,javascript,css,reactjs,Javascript,Css,Reactjs,我有一个组件,它在我的电子商务应用程序中显示了我产品的全部细节,每次我打开不同的产品时,我在控制台中都会看到这个错误,这就是错误 Uncaught (in promise) Error: Element is probably not rendered to the DOM - something with your layout or CSS definition at e.<anonymous> (index.tsx:197) at index.esm.js:51

我有一个组件,它在我的电子商务应用程序中显示了我产品的全部细节,每次我打开不同的产品时,我在控制台中都会看到这个错误,这就是错误

Uncaught (in promise) Error: Element is probably not rendered to the DOM - something with your layout or CSS definition
    at e.<anonymous> (index.tsx:197)
    at index.esm.js:516
    at Object.next (index.esm.js:516)
    at s (index.esm.js:516)

class FullProduct extends Component {
  state = {
    purchasing: false,
    favIcon: this.props.isFavourite,
    isFavourite: this.props.isFavourite,
    show: false,
    isRemove: null,
    showFedback: false,
    isBasketAdd: false,
    showBasketFedback: false
  };

  // get product data
  loadData = () => {
    if (this.props.match.params.id) {
      if (
        !this.props.product ||
        (this.props.product &&
          this.props.product.pid !== this.props.match.params.id)
      ) {
        this.props.onGetFullProduct(this.props.match.params.id);
      }
    }
  };

  // get isFavourite info
  getData = async () => {
    db.collection("userFavourites")
      .doc(this.props.user.uid)
      .get()
      .then(res => {
        let favourites = res.data();
        const isFavourite = favourites
          ? favourites[this.props.match.params.id]
          : false;
        if (isMount) {
          this.setState({ isFavourite: isFavourite, favIcon: isFavourite });
        }
      })
      .catch(err => {
        if (isMount) this.setState({ error: err });
      });
  };

  componentDidMount() {
    isMount = true;
    if (isMount) {
      if (this.props.user) {
        this.getData();
      }
      this.loadData();
    }
  }

  componentWillUnmount() {
    isMount = false;
  }

  componentDidUpdate() {
    if (isMount) {
      this.loadData();
    }
  }

  discountHandler = (price, discount) => {
    let newPrice = price - (price * discount) / 100;
    return Math.round(newPrice * 100) / 100;
  };

  purchaseHandler = () => {
    if (isMount) this.setState({ purchasing: true });
  };

  purchaseCancelledHandler = () => {
    if (isMount) this.setState({ purchasing: false });
  };

  purchaseContinuedHandler = () => {
    this.props.onCheckPurchasing();
    if (this.props.user) {
      this.props.history.push("/checkout");
    }
  };

  loginBtnClicked = () => {
    this.props.history.push("/login");
    this.props.onCheckPurchasing();
  };

  registerBtnClicked = () => {
    this.props.history.push("/register");
    this.props.onCheckPurchasing();
  };

  onMouseEnterHandler = e => {
    let fav = this.state.isFavourite;
    fav = !fav;
    if (isMount)
      this.setState({
        favIcon: fav
      });
  };

  onMouseLeaveHandler = () => {
    let fav = this.state.isFavourite;
    if (isMount) this.setState({ favIcon: fav });
  };

  favBtnHandler = productId => {
    if (this.props.user) {
      let isFavourite = this.state.isFavourite;
      if (isFavourite && isMount) {
        this.setState({ isRemove: true });
      } else {
        this.setState({ isRemove: false });
      }
      if (isMount) this.setState({ isFavourite: !isFavourite });
      db.collection("userFavourites")
        .doc(this.props.user.uid)
        .update({
          [productId]: !isFavourite
        })
        .then(res => {
          if (isMount) this.setState({ show: true });
          setTimeout(() => {
            if (isMount) this.setState({ show: false });
          }, 5000);
        })
        .catch(err => {
          let error = err.message.slice(0, 21);
          if (error === "No document to update") {
            db.collection("userFavourites")
              .doc(this.props.user.uid)
              .set({
                [productId]: !isFavourite
              })
              .catch(err => {
                if (isMount) this.setState({ error: err });
              });
          }
        });
    } else {
      if (isMount) this.setState({ showFedback: true });
      setTimeout(() => {
        if (isMount) this.setState({ showFedback: false });
      }, 5000);
    }
  };

  loginClickedHandler = () => {
    this.props.history.push("/login");
  };

  cancelClickedHandler = () => {
    if (isMount) this.setState({ showFedback: false });
  };

  addToBasketHandler = () => {
    let productId = this.props.product.pid;
    let basketProductIds = [];
    this.props.basketProducts.forEach(product =>
      basketProductIds.push(product.pid)
    );
    let index = basketProductIds.findIndex(element => element === productId);
    if (index === -1) {
      this.props.onAddProductToBasket(this.props.product);
      if (isMount)
        this.setState({ isBasketAdd: true, showBasketFedback: true });
    } else {
      this.props.onRemoveProductFromBasket(this.props.product);
      if (isMount)
        this.setState({ isBasketAdd: false, showBasketFedback: true });
    }
    setTimeout(() => {
      if (isMount) this.setState({ showBasketFedback: false });
    }, 5000);
  };

  render() {
    // get product image links
    if (this.props.loaded) {
      let images = this.props.product.images
        .map(link => {
          return link.match("/products/");
        })
        .map(link => {
          const newlink = link.input.slice(link.index);
          const newlink2 = newlink.slice(0, -4);
          return { publicId: newlink2 };
        });

      // create gallery widget
      const myWidget = window.cloudinary.galleryWidget({
        cloudName: "e-bazaar",
        container: "#my-gallery",
        mediaAssets: images,
        displayProps: {
          mode: "classic"
        },
        transition: "slide",
        themeProps: {
          active: "#49c58f"
        },
        aspectRatio: "square",
        zoomProps: {
          trigger: "click"
        },
        carouselLocation: "left",
        carouselStyle: "indicators",
        indicatorProps: {
          shape: "round"
        }
      });
      myWidget.render();
    }

    // detail widget
    let priceSection = null;
    if (this.props.product) {
      price = Math.round(this.props.product.price * 100) / 100;
      priceSection = (
        <p>
          <span style={{ fontWeight: "bold", color: "#393D46" }}>Price: </span>
          <span className={classes.Price}> {price.toFixed(2)}$</span>
        </p>
      );
      if (this.props.product.discount) {
        newPrice = this.discountHandler(
          this.props.product.price,
          this.props.product.discount
        );
        priceSection = (
          <p className={classes.priceSection}>
            <span className={classes.priceLabel}>Price:</span>
            <span className={classes.Discount}>{price}$</span>
            <span className={classes.Price}>{newPrice.toFixed(2)}$</span>
          </p>
        );
      }
    }

    let fedback = (
      <div className={classes.fedback}>
        {this.state.isRemove ? (
          <p>
            Removed From Favourites <HiOutlineEmojiSad />
          </p>
        ) : (
          <p>
            Added To Favourites <HiOutlineEmojiHappy />
          </p>
        )}
      </div>
    );

    let basketFedback = (
      <div className={classes.basketFedback}>
        {!this.state.isBasketAdd ? (
          <p>
            Removed From Basket <HiOutlineEmojiSad />
          </p>
        ) : (
          <p>
            Added To Basket <HiOutlineEmojiHappy />
          </p>
        )}
      </div>
    );

    let favIcon = null;
    if (this.state.isFavourite && !this.state.favIcon) {
      favIcon = (
        <BsHeart
          style={{ color: "#626669" }}
          id="icon"
          className={classes.favIcons}
        />
      );
    } else if (this.state.isFavourite && this.state.favIcon) {
      favIcon = (
        <BsHeartFill
          style={{ color: "#ff5e78" }}
          id="icon"
          className={classes.favIcons}
        />
      );
    } else if (!this.state.isFavourite && this.state.favIcon) {
      favIcon = (
        <BsHeartFill
          style={{ color: "#ff5e78" }}
          id="icon"
          className={classes.favIcons}
        />
      );
    } else if (!this.state.isFavourite && !this.state.favIcon) {
      favIcon = (
        <BsHeart
          style={{ color: "#626669" }}
          id="icon"
          className={classes.favIcons}
        />
      );
    }

    let modal = (
      <div className={classes.modalFedback}>
        <p>
          You have to login to your account, in order to add product to your
          wishlist <HiOutlineEmojiHappy />
        </p>
        <Button btnType="Danger" clicked={this.cancelClickedHandler}>
          CANCEL
        </Button>
        <Button btnType="Success" clicked={this.loginClickedHandler}>
          LOGIN
        </Button>
      </div>
    );

    let detail = null;
    if (this.props.product) {
      detail = (
        <div className={classes.detail}>
          <h1 className={classes.title}>{this.props.product.title}</h1>
          <p className={classes.desc}>{this.props.product.description}</p>
          <p className={classes.brand}>
            <span style={{ fontWeight: "bold", paddingRight: "10px" }}>
              Brand:
            </span>
            {this.props.product.brand}
          </p>
          <p className={classes.amount}>
            <span style={{ fontWeight: "bold", paddingRight: "10px" }}>
              Amount:
            </span>
            {this.props.product.amount}
            <span style={{ paddingLeft: "5px" }}></span>
            available
          </p>
          {priceSection}
          <div className={classes.ReviewSection}>
            <Rating rating={this.props.product.rating} />
          </div>
          <div className={classes.MenuIcons}>
            <span
              className={classes.iconDiv}
              onMouseEnter={e => this.onMouseEnterHandler(e)}
              onMouseLeave={this.onMouseLeaveHandler}
              onClick={() => this.favBtnHandler(this.props.match.params.id)}
            >
              {favIcon}
            </span>
            <span className={classes.iconDiv} onClick={this.addToBasketHandler}>
              <Icon src={basket1} src2={basket2} />
            </span>
            <Button btnType="Primary" clicked={this.purchaseHandler}>
              <FaShoppingCart /> SHOP NOW
            </Button>
          </div>
        </div>
      );
    }

    const screen = !this.props.loading ? (
      <Aux>
        <div id="my-gallery" className={classes.Gallery}></div>
        {detail}
      </Aux>
    ) : (
      <Spinner />
    );

    let orderSummary = null;
    if (this.props.product) {
      orderSummary = (
        <OrderSummary
          product={this.props.product}
          price={this.props.product.discount ? newPrice : price}
          purchaseCancelled={this.purchaseCancelledHandler}
          purchaseContinued={this.purchaseContinuedHandler}
        />
      );
    }

    if (!this.props.user) {
      orderSummary = (
        <div>
          <p className={classes.happyIcon}>
            <HiOutlineEmojiHappy />
          </p>
          <p className={classes.noUserWarning}>
            You have to login or create an account to complete your order...
          </p>
          <div className={classes.awayBtn}>
            <Button btnType="Success" clicked={this.loginBtnClicked}>
              LOGIN
            </Button>
          </div>
          <div className={classes.awayBtn}>
            <Button
              btnType="Success"
              clicked={this.registerBtnClicked}
              className={classes.awayBtn}
            >
              REGISTER
            </Button>
          </div>
        </div>
      );
    }

    return (
      <Aux>
        <Modal
          show={this.state.showFedback}
          ModalClosed={this.cancelClickedHandler}
        >
          {modal}
        </Modal>
        {this.props.noProduct ? (
          <NotFound />
        ) : (
          <Aux>
            <div className={classes.FullProduct}> {screen} </div>
            <Modal
              show={this.state.purchasing}
              ModalClosed={this.purchaseCancelledHandler}
            >
              {orderSummary}
            </Modal>
          </Aux>
        )}
        {this.state.show ? fedback : null}
        {this.state.showBasketFedback ? basketFedback : null}
      </Aux>
    );
  }
}

const mapStateToProps = state => {
  return {
    productId: state.products.productId,
    product: state.fullProduct.product,
    loading: state.fullProduct.loading,
    loaded: state.fullProduct.loaded,
    error: state.fullProduct.error,
    noProduct: state.fullProduct.noProduct,
    user: state.auth.user,
    isFavourite: state.products.isFavourite,
    basketProducts: state.fullProduct.basketProducts
  };
};

const mapActionsToProps = dispatch => {
  return {
    onGetFullProduct: id => dispatch(actions.getFullProduct(id)),
    onCheckPurchasing: () => dispatch(actions.checkPurchasing()),
    onAddProductToBasket: product =>
      dispatch(actions.addProductsToBasket(product)),
    onRemoveProductFromBasket: product =>
      dispatch(actions.removeProductsFromBasket(product))
  };
};

export default connect(
  mapStateToProps,
  mapActionsToProps
)(withRouter(FullProduct));
 
.FullProduct {
    margin-top: 150px;
    padding: 50px 10px 20px 10px;
    display: flex;
    align-items: flex-start;
    flex-direction: row;
    justify-content: center;
    flex-wrap: wrap;
    column-gap: 30px;
    row-gap: 30px;
    overflow: hidden;
}

.Gallery {
    width: 35%;
    padding: 20px;
    border-radius: 10px;
    box-shadow: rgba(36, 37, 38, 0.08) 0px 6px 15px 0px;
    transition: all 0.3s cubic-bezier(.25, .8, .25, 1);
    border: 1px solid white;
    background-color: white;
    margin: 0px 10px 20px 10px;
}

.detail {
    width: 40%;
    padding: 20px;
    border-radius: 10px;
    box-shadow: rgba(36, 37, 38, 0.08) 0px 6px 15px 0px;
    transition: all 0.3s cubic-bezier(.25, .8, .25, 1);
    border: 1px solid white;
    background-color: white;
    margin: 0 0 20px 0;
}

.title {
    color: #393D46;
    font-size: 3rem;
}

.desc {
    color: #9fa4af;
    text-align: left;
    white-space: pre-wrap;
}

.brand {
    color: #393D46;
}

.amount {
    color: #393D46;
}

.priceLabel {
    font-weight: bold;
    color: #393D46;
    padding-right: 10px;
}

.Price {
    font-size: 2.5rem;
    color: #45C48B;
    margin: 20px 7px;
}

.Discount {
    font-size: 1.8rem;
    color: #9ba5af;
    text-decoration: line-through;
    text-decoration-color: #172B4D;
    text-decoration-thickness: 3px;
}

.ReviewSection {
    margin: 20px 0;
}

.iconDiv {
    display: inline-block;
    position: relative;
    top: 10px;
}

.fedback {
    background: #ff5e78;
    padding: 0px 5px;
    border-radius: 10px;
    position: fixed;
    z-index: 80;
    right: 25px;
    bottom: 50px;
}

.fedback>p {
    color: white;
    margin: 10px 5px;
    font-size: large;
}

.basketFedback {
    background: #45C48B;
    padding: 0px 5px;
    border-radius: 10px;
    position: fixed;
    z-index: 80;
    right: 25px;
    bottom: 50px;
}

.basketFedback>p {
    color: black;
    margin: 10px 5px;
    font-size: large;
}

.modalFedback {
    background: white;
    padding-bottom: 20px;
}

.modalFedback>p {
    font-size: larger;
    margin-bottom: 40px;
}

.favIcons {
    font-size: 30px;
    padding-right: 10px;
}

.iconDiv img {
    display: inline-block;
    padding-right: 10px;
    width: 30px;
    height: 30px;
}

.noUserWarning {
    margin: 40px 20px;
}

.happyIcon {
    font-size: xx-large;
    color: #393D46
}

.awayBtn {
    display: inline-block;
}

@media(max-width:730px) {
    .detail {
        width: 80%;
    }
    .Gallery {
        width: 80%;
    }
}

@media(max-width:389px) {
    .priceLabel {
        display: block;
    }
    .Discount {
        display: block;
    }
    .Price {
        display: block;
    }
}

@media(max-width:280px) {
    .iconDiv {
        top: -10px;
    }
    .awayBtn {
        margin: 10px 0;
    }
}