为了账号安全,请及时绑定邮箱和手机立即绑定

useEffect 在进行 firestore 调用时覆盖状态而不是附加值

useEffect 在进行 firestore 调用时覆盖状态而不是附加值

皈依舞 2022-12-18 16:32:28
const [data, setData] = useState([])         const getDataFromFirebase = async () => {         let response = await firestore.collection('someDatabase').get()         response.forEach(item => setData([...data, item.data().name]))              }        useEffect(() => {       getDataFromFirebase()    },[])数据被最新值覆盖,而不是将所有值添加到数组中。
查看完整描述

4 回答

?
一只甜甜圈

TA贡献1836条经验 获得超5个赞

原因是添加项目所花费的时间非常少,这就是为什么在反映之前,它被覆盖了。您必须在 setData 中使用 prevState 。试试这个:


const [data, setData] = useState([])


const getDataFromFirebase = async () => {

let response = await firestore.collection('someDatabase').get()

response.forEach(item => setData(prevState => ([

    ...prevState, item.data().name])

  );

}

useEffect(() => {

  getDataFromFirebase()

  },[])


查看完整回答
反对 回复 2022-12-18
?
宝慕林4294392

TA贡献2021条经验 获得超8个赞

在中使用回调setData


setData(prevState => ([

    ...prevState, item.data().name

]));


查看完整回答
反对 回复 2022-12-18
?
12345678_0001

TA贡献1802条经验 获得超5个赞

let response = await firestore.collection('someDatabase').get()

response.forEach(item => setData([...data, item.data().name]))

我不熟悉firestore,但是这个承诺将被解决一次,你应该做这样的事情:


const dataToAdd = response.map(item => item.data().name)

setData(prevState => ([...prevState, ...dataToAdd])

每次setData调用时您都在重新渲染组件,您不应该在同步循环中执行此操作。


prevState在这里是必需的,因为您正在使用异步函数。dataToAdd从理论上讲,如果您不在其他任何地方更改状态,则在使用解决方案后它应该可以在没有它的情况下工作。


查看完整回答
反对 回复 2022-12-18
?
杨魅力

TA贡献1811条经验 获得超6个赞

[]在您下面的代码中,即使您稍后更改数据,数据的值也将始终存在。


const getDataFromFirebase = async () => {

         let response = await firestore.collection('someDatabase').get()

         response.forEach(item => setData([...data, item.data().name]))

         

     }

这就是文档所说的


在功能组件的主体(称为 React 的渲染阶段)内不允许发生突变、订阅、计时器、日志记录和其他副作用。这样做会导致 UI 中出现令人困惑的错误和不一致。


在每个循环中调用 setData 不是一个好主意。填充一个数组并将其传递给setData循环完成后。


     const getDataFromFirebase = async () => {

         let response = await firestore.collection('someDatabase').get();

         let newData = [];

         response.forEach(item => newData.push(item.data().name));


         // now set the new data

         setData(prevData=> ([...prevData, ...newData]));

         

         // or you can use Array.concat

         // setData(prevData=> (prevData.concat(newData)));

     }


查看完整回答
反对 回复 2022-12-18
  • 4 回答
  • 0 关注
  • 157 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号