开发者问题收集

打开数组时 Firebase undefined 不是对象

2021-06-26
647

所以这真的很奇怪

这是我的代码,当它工作时

useEffect(() => {
        // Alleen preview
           async function getTracksData() {
                let TrackData = await firebase
                    .firestore()
                    .collection('TrackScreen')
                    .doc('LeerjarenData')
                    .get();
                if (!TrackData.exists) {
                    console.log('Geen data')
                } else {
                    let TrackDatav2 = TrackData.data();
                    setTrackScreenData(TrackDatav2) 
                }
           } getTracksData()
            // SNAPSHOT USER DATA
            db.collection("users").doc(currentUserUID)
                .onSnapshot((doc) => {
                    setUserData(doc.data());
                });
    }, [])

    console.log(trackscreenData.data)

这工作得很好,但是当我将我的控制台更改为

console.log(trackscreenData.data[0]

它给了我这个错误

TypeError: undefined is not an object (evaluating 'trackscreenData.data[0]')

然后当我再次将我的控制台更改为

console.log(trackscreenData.data)

它可以工作,当我更改回

console.log(trackscreenData.data[0])

并保存更改时它会给我我想要的数据

我做错了什么?

2个回答

简而言之,您试图在异步调用中尚未准备好数据时使用它。

要处理数据尚未完成加载的情况,您应该使用:

console.log(trackscreenData && trackscreenData.data)

根据代码中的模式,您在组件顶部有这些行。

const { currentUserID } = useAuth(); // or similar

const [userData, setUserData] = useState();

const [trackscreenData, setTrackScreenData] = useState();
// NOTE: check for typos: "trackscreenData" !== "trackScreenData"

在代码 首次渲染 时, trackscreenData 将为 未定义 ,因为您尚未将初始状态传递到 useState() 方法中。

const [trackscreenData, setTrackScreenData] = useState(/* initial state */);
// `trackscreenData` initially set to `null`
const [trackscreenData, getTracksData] = useState(null);

// `trackscreenData` initially set to `[]`
const [trackscreenData, getTracksData] = useState([]);

// `trackscreenData` initially set to the result of the function,
// an array containing the elements 0 through 99. The function is
// only executed once to set the first value.
// trackscreenData = [0, 1, 2, 3, ... , 97, 98, 99];
const [trackscreenData, getTracksData] = useState(() => {
  Array.from({length: 100})
    .map((_, i) => i);
}

当 React 执行您的代码时,任何从 useState 调用(例如 setTrackScreenData )返回的 setter 调用都会 排队 。仅当您的代码执行完毕后,才会对它们进行评估并触发任何新的渲染。

const [count, setCount] = useState(0); // `count` is initially set to `0`

useEffect(() => {
  if (count < 10) {
    setCount(count + 1);
  }
})

console.log(count);

console.log("rendered");

// Console logs:
// > "0"
// > "rendered"
// > "1"
// > "rendered"
// > ...
// > "9"
// > "rendered"
// > "10"
// > "rendered"

您对用户数据的提取应在其自己的 useEffect 调用中进行,并应返回其取消订阅函数:

useEffect(() => {
  if (!currentUserUID) {
    setUserData(null); // user not signed in
    return;
  }

  // SNAPSHOT USER DATA
  return db.collection("users") // <- note the return here
    .doc(currentUserUID)
    .onSnapshot((doc) => {
      setUserData(doc.data());
    });
}, [currentUserUID]);
useEffect(() => {
  let disposed = false;

  // Alleen preview
  async function getTracksData() {
    let TrackData = await firebase
      .firestore()
      .collection('TrackScreen')
      .doc('LeerjarenData')
      .get();

    if (disposed) return; // component was removed, do nothing

    if (!TrackData.exists) {
      console.log('Geen data')
    } else {
      let TrackDatav2 = TrackData.data();
      setTrackScreenData(TrackDatav2) 
    }
  }

  getTracksData()
    .catch((err) => console.error(err)); // don't forget to handle errors!

  return () => disposed = true; // ignore result if component disposed
}, []);
samthecodingman
2021-06-26

您通过 .doc(...) 指定文档 ID,因此您将获得 DataSnapshot 作为响应,它不是数组。

如果您使用类似 .where(...) 的查询,那么它将返回 QuerySnapshot

A QuerySnapshot contains zero or more DocumentSnapshot objects representing the results of a query. The documents can be accessed as an array via the docs property or enumerated using the forEach method. The number of documents can be determined via the empty and size properties.

因此,如果您仅通过这种方式获取单个文档,则无需通过 [0] 访问文档,因为它不是数组。您可以简单地通过 dataSnapshot.data() 访问数据。

虽然我看不到 trackscreenData 在哪里定义?

useEffect(() => {
        // Alleen preview
           async function getTracksData() {
                let TrackData = await firebase
                    .firestore()
                    .collection('TrackScreen')
                    .doc('LeerjarenData')
                    .get();
                if (!TrackData.exists) {
                    console.log('Geen data')
                } else {
                    let TrackDatav2 = TrackData.data();
                    setTrackScreenData(TrackDatav2) 
                    console.log(trackScreenData)
                }
           } 
    }, [])
Dharmaraj
2021-06-26