创建加载程序

Jos*_*ton 2 reactjs google-cloud-firestore

所以我试图用 React 和 firebase firestore 制作一个加载屏幕。基本上,每当我的应用程序从 firestore 获取数据时,我想创建一个加载程序。

编辑:例如,我尝试做类似的事情:

const [data, setData]=useState([])
const [loader, setLoader]=useState(false)


db.collection('conversations').doc(id).onSnapshot(snap=>{
setData(snap.data())
}).then(()=>{
setLoader(true)
})
Run Code Online (Sandbox Code Playgroud)

但这会将加载器设置为 true,但我想在访问数据之前将加载器设置为 true,一旦检索到数据,我想将加载器设置为 false。

有什么建议么?

Lea*_*mer 5

.onSnapShot()不会做你认为它会做的事情 - 它附加一个监听器来更改文档,该监听器将始终至少触发一次,然后进行任何进一步的更改 - 但不一定立即!它也不返回承诺;它返回一个取消订阅函数 - 当作为 useEffect 挂钩的一部分时很有用。

您的代码中发生的情况是附加侦听器,然后立即setLoader(true)调用- 由于 Javascript 事件循环,远远早于调用侦听器函数。

如果您打算在返回数据setLoader(true)调用,则至少需要:

db.collection('conversations').doc(id).onSnapshot(snap=>{
setData(snap.data())
setLoader(true)
})
Run Code Online (Sandbox Code Playgroud)

我会注意到,这本身并不能处理快照中可能出现的错误。

它更可能是 useEffect 挂钩的一部分,这将有助于在卸载组件时卸载监听器

useEffect(() => {
  return db
  .collection('conversations')
  .doc(id)
  .onSnapshot(snap=>{
    setData(snap.data());
    setLoader(true)
  })
}, []);

Run Code Online (Sandbox Code Playgroud)

如果,otoh,您只想获取一次文档,您将需要使用 .get(),它返回带有 DocumentSnapshot 的承诺

db.collection('conversations').doc(id).get().then(snap=>{
setData(snap.data())
}).then(()=>{
setLoader(true)
})
Run Code Online (Sandbox Code Playgroud)

按照评论中的要求,对于单次提取:

useEffect(() => {
  // no need for a return for a single get
  setLoader(true)
  db
  .collection('conversations')
  .doc(id)
  .get()
  .then(snap=>{
    setData(snap.data());
    setLoader(false);
  })
}, [*whatever state variable will change to start the process*]);

Run Code Online (Sandbox Code Playgroud)

...对于听众(上面),采取完全不同的方法:

const [data, setData]=useState([])
const [loader, setLoader]=useState(true) //DEFAULTS TO LOADING

useEffect(() => {
  return db
  .collection('conversations')
  .doc(id)
  .onSnapshot(snap=>{
    setData(snap.data());
    setLoader(false) //when the data is ready THE FIRST TIME
  })
}, []);

Run Code Online (Sandbox Code Playgroud)

对于侦听器的任何更新,无需执行任何操作将状态设置为 LOADING - 这将由状态管理和 setData() 处理。每次 Firestore 调用侦听器时,这些更改都会显示在后续渲染中