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

时间:2020-08-01 16:07:26

标签: javascript reactjs firebase google-cloud-firestore use-effect

const [data, setData] = useState([])
    
     const getDataFromFirebase = async () => {
         let response = await firestore.collection('someDatabase').get()
         response.forEach(item => setData([...data, item.data().name]))
         
     }
    
    useEffect(() => {
       getDataFromFirebase()
    },[])

数据将被最新值覆盖,而不是将所有值都添加到数组中。

5 个答案:

答案 0 :(得分:1)

使用setData

中的回调
setData(prevState => ([
    ...prevState, item.data().name
]));

答案 1 :(得分:1)

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

master

答案 2 :(得分:1)

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使用解决方案之后,如果没有它,它应该可以工作。

答案 3 :(得分:0)

尝试一次此火setState,但在之前构建数组:

const [data, setData] = useState([])
    
 const getDataFromFirebase = async () => {
    let response = await firestore.collection('someDatabase').get()
    const d = response.map(item=> item.data().name)
    setData(d)  
  }
    
 useEffect(() => {
       getDataFromFirebase()
 },[])

多次射击setData会导致多次重投,因此这里会射击一次。

答案 4 :(得分:0)

在您的代码下方,即使以后更改数据,数据值也始终为[]

const getDataFromFirebase = async () => {
         let response = await firestore.collection('someDatabase').get()
         response.forEach(item => setData([...data, item.data().name]))
         
     }

这就是医生所说的

突变,订阅,计时器,日志记录和其他副作用是 不允许在功能组件的主体内部(指 作为React的渲染阶段)。这样做会导致混淆的错误和 用户界面中的不一致。

在每个循环中调用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)));
     }