【问题标题】:Getting map data using React from firestore使用 React 从 Firestore 获取地图数据
【发布时间】:2021-03-19 20:26:52
【问题描述】:

我无法弄清楚如何在 reactjs 中从 Firestore 获取地图数据。我的代码不断出错,说“对象作为 React 无效”。有人可以给我举个例子,或者给我看一个下面有我的数据库的例子吗?

import React, { useState, useEffect } from "react";
import { firestore } from "../../../FireBase/FireBase";
import CartItem from "./CartItem";
const CartPage = (props) => {
  const [cart, setCart] = useState(null);
  useEffect(() => {
    const fetchCart = async () => {
      const doc = await firestore
        .collection("Users")
        .doc("CfL5uszL3CTE1nIQTgDrKK5q4OV2")
        .get();

      const data = doc.data();
      console.log("data " + data);
      if (!data) {
        // document didn't exist
        console.log("hit null");
        setCart(null)
      } else {
        console.log("hit");
        setCart(data.cart);
      }
      console.log("cart " + cart);
    }

    fetchCart();
  }, []);

  if (!cart) {
    // You can render a placeholder if you like during the load, or just return null to render nothing.
    return null;
  }

  return (
    <div className="cartpage">
      <h1>cart</h1>
      <div className="cart">
        {cart.map(cartItem => (
          <div key={cartItem.id}>{cartItem.name}</div>
        ))}
      </div>
    </div>
  );
};

export default CartPage;

【问题讨论】:

  • 你能在codesandbox或类似平台上分享你的代码吗?很难从图像中调试它。
  • @TomaszKisiel 我已经添加了我的代码

标签: reactjs google-cloud-firestore


【解决方案1】:

您得到的错误是因为您从组件返回了一个承诺(您已将其设为异步函数,并且异步函数返回承诺)。在 react 中渲染不能返回 Promise 和其他任意对象。您需要有一个状态变量来保存您的数据。在第一次渲染时,您将没有数据,然后您将使用 useEffect 来获取数据并更新状态

此外,您在尝试获取和访问数据的方式上存在一些错误。您正在调用 .get("Cf...V2"),但 .get 不带参数。如果要指定要获取的文档,请使用 .doc() 函数。 .get() 然后将返回一个承诺,因此您需要在尝试访问它的任何属性之前等待它。您获得的数据将是一个对象,其中包含屏幕截图右侧的所有属性,您需要从中提取 cart 属性。

简而言之,我推荐如下内容:

const CartPage = (props) => {
  const [cart, setCart] = useState(null);
  useEffect(() => {
    const fetchCart = async () => {
      const doc = await firestore
        .collection("Users")
        .doc("CfL5uszL3CTE1nIQTgDrKK5q4OV2")
        .get();

      const data = doc.data();
      if (!data) {
        // document didn't exist
        setCart(null)
      } else {
        setCart(data.cart);
      }
    }

    fetchCart();
  }, []);

  if (!cart) {
    // You can render a placeholder if you like during the load, or just return null to render nothing.
    return null;
  }

  return (
    <div className="cartpage">
      <h1>cart</h1>
      <div className="cart">
        {cart.map(cartItem => (
          <div key={cartItem.id}>{cartItem.name}</div>
        ))}
      </div>
    </div>
  );
};

【讨论】:

  • 我已经实现了你的代码添加我得到了一些错误。这是控制台日志数据 [object Object] hit cart null
  • 不知道你添加了什么代码,我不知道那些日志语句的意义。
  • 所以我认为这与您如何从用户那里调用购物车有关。你知道为什么购物车是空的吗?
  • 我复制了您的代码并尝试使用它以确保它有效。所以我运行的代码是上面问题的更新代码。我刚刚添加了日志以查看您的工作情况
  • data [object Object] 这意味着它取回了数据。如果将日志语句更改为console.log('data', data),您可以更好地查看它。 hit 这是确认它进入了elsecart null 这告诉你cart 的值为空当效果开始时。这是完全可以预料的。调用 setCart 不会改变本地 const 的值,所以这个 log 语句没有用。如果要验证组件是否重新渲染,请在组件的主体中放置一条日志语句,而不是在效果中。
【解决方案2】:

我不认为你可以用这种方式创建异步组件。您在组件中返回的内容应该是简单的 JSX 代码。如果你想在组件中异步做一些事情,你应该把它包装在 useEffect 钩子里。

const CartPage = (props) => {
  const [ cart, setCart ] = useState(null)

  useEffect(() => {
    const inner = async () => {
      const ref = await firestore
        .collection("Users")
        .get("CfL5uszL3CTE1nIQTgDrKK5q4OV2").cart;

      setCart(
        ref.map((item) => ({
          id: item.id,
          name: item.name
        }))
      );
    };

    inner();
  }, []);

  return (
    <div className="cartpage">
      <h1>cart</h1>
      <div className="cart"></div>
    </div>
  );
};

【讨论】:

  • 现在我收到一个错误“未处理的拒绝(TypeError):无法读取未定义的属性'map'”
  • 表示 ref 不是数组。可能这个命令有问题firestore.collection("Users").get("CfL5uszL3CTE1nIQTgDrKK5q4OV2").cart;是正确的集合名称和正确的ID?
猜你喜欢
  • 2020-08-29
  • 2019-09-30
  • 2022-11-24
  • 2021-01-06
  • 2021-07-27
  • 2020-03-07
  • 1970-01-01
  • 2020-12-14
  • 2021-08-17
相关资源
最近更新 更多