reactjs - 创建加载器
问题描述
因此,我正在尝试使用 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)
})
但这会将加载程序设置为true,但我想在访问数据之前将加载程序设置为true,一旦检索到数据,我想将加载程序设置为false。
有什么建议么?
解决方案
.onSnapShot()
不会做你认为它做的事——它附加一个监听器来监听对文档的更改,它总是至少触发一次,然后再进行任何进一步的更改——但不一定立即!它也不返回承诺;它返回一个取消订阅函数 - 当是 useEffect 钩子的一部分时很有用。
您的代码中发生的事情是附加了侦听器,然后立即setLoader(true)
被调用 - 因为 Javascript 事件循环,远在调用侦听器函数之前。
如果您打算在返回数据后setLoader(true)
调用,则至少需要:
db.collection('conversations').doc(id).onSnapshot(snap=>{
setData(snap.data())
setLoader(true)
})
我会注意到这本身并不能处理快照中可能出现的错误。
它更有可能是 useEffect 钩子的一部分,这将有助于在卸载组件时卸载侦听器
useEffect(() => {
return db
.collection('conversations')
.doc(id)
.onSnapshot(snap=>{
setData(snap.data());
setLoader(true)
})
}, []);
如果,otoh,您只想获取一次文档,您将需要使用 .get(),它确实返回带有 DocumentSnapshot 的承诺
db.collection('conversations').doc(id).get().then(snap=>{
setData(snap.data())
}).then(()=>{
setLoader(true)
})
并根据评论中的要求,进行一次提取:
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*]);
...对于听众(上图),采取完全不同的方法:
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
})
}, []);
对于侦听器的任何更新,无需执行任何操作来将状态设置为 LOADING - 这将由状态管理和 setData() 处理。每次 Firestore 调用侦听器时,这些更改只会显示在后续渲染中
推荐阅读
- php - Breadcrumbs not displaying in Avada as expected with custom post type
- python - Why does my code only write the first rows into my csv? I'm looping through multiple websites and print function seems to grab all the values
- objective-c - 将块传递给纯 C 函数所需的语法是什么?
- python - What is the best way to implement an element-wise cosine similarity in Python?
- python - 如何在 Tensorflow 和 Keras 中正确建模 LSTM
- python - 在 initializable_iterator 不可用的急切执行模式下,如何动态提供 tf.data.Dataset?
- visual-studio-2013 - 卸载 WiX 3.11 并降级到 3.9 后,一个项目仍然想要 3.11
- ruby-on-rails - 生产“autoload_paths”中缺少“app”下的自定义目录
- c# - 在 EF Core 2.2 中更新自有实体
- javascript - 如何在一个自定义控件中处理来自不同模型的两组