【问题标题】:Reactjs doesen't re render after setState to array在 setState 到数组后 Reactjs 不会重新渲染
【发布时间】:2022-01-14 17:52:33
【问题描述】:

当我完成从数据库中获取数据并使用状态 setValue 并传递数组时,渲染函数不会再次渲染。

我设置数组的代码

function getNotifiche(){
     onSnapshot(collection(db, "Users",auth.currentUser.uid, "Notifiche"), async (snapNotifiche) => {
            const notifichee = [];
            snapNotifiche.forEach(async notificaDoc => {

                const docRef = doc(db,"Users",notificaDoc.data().Invitato);
                const userData = await getDoc(docRef);

                
                        notifichee.push({
                            "data":notificaDoc.data(),
                            "invitante":userData.data()
                            })
               });
          
            setListaNotifiche(notifichee);

});

这是在返回函数中:

 {         
        (listaNotifiche.map((notifica,index)=>{
            return(<div key={index}>
                <label>Invitato da {notifica.invitante.Username} in data{new Date(notifica.data.DataInvito.seconds * 1000).toString()}</label>
                <button>Partecipa</button>
                <button>Elimina</button> 
                </div>);
        }))
    }

所以我也尝试使用 setListaNotifiche([...notifichee]) 但我收到错误:TypeError: Cannot read properties of undefined (reading 'map')

【问题讨论】:

  • 你做了哪些调试来确认状态没有被更新?并且该错误没有发生在状态完全更新? getNotifiche 什么时候被调用过?在那之前的状态值是多少?初始状态是什么?请提供minimal reproducible example 来证明问题。
  • @David 我已经控制台记录了数组,当它已满时,我没有看到任何显示。在代码的第一个版本中,我只推送了数组中的 notificheDoc.data(),现在它可以工作了,因为数组是由渲染没有更新的对象组成的

标签: javascript reactjs


【解决方案1】:

.forEach 对承诺或异步函数一无所知。当.forEach 完成时,notifichee 仍然是一个空数组,然后您使用一个空数组设置状态。一段时间后,数组将被修改为包含数据,但这是在组件渲染之后发生的。

相反,在创建数组和设置状态之前,您需要等待 Promise 完成。您可以使用.map 创建一个promise 数组,然后Promise.all 将它们组合成一个promise,然后等待该promise 获取数据数组:

onSnapshot(
  collection(db, "Users", auth.currentUser.uid, "Notifiche"),
  async (snapNotifiche) => {
    const promises = snapNotifiche.docs.map(async (notificaDoc) => {
      const docRef = doc(db, "Users", notificaDoc.data().Invitato);
      const userData = await getDoc(docRef);
      return {
        data: notificaDoc.data(),
        invitante: userData.data(),
      }
    })
    const notifichee = await Promise.all(promises);

    setListaNotifiche(notifichee);
  }
);

【讨论】:

  • 我知道 snapNotifiche.map 不是一个函数
  • 对不起,应该是snapNotifiche.docs.map
  • 是的,谢谢!
猜你喜欢
  • 2021-12-06
  • 2016-09-09
  • 2019-01-24
  • 1970-01-01
  • 2018-09-01
  • 2021-08-04
  • 1970-01-01
  • 2019-03-05
  • 1970-01-01
相关资源
最近更新 更多