![](/img/trans.png)
[英]Implementing multiple Firestore calls at different times within useEffect React hook
[英]useEffect overriding the state instead of appending the values while making firestore calls
const [data, setData] = useState([])
const getDataFromFirebase = async () => {
let response = await firestore.collection('someDatabase').get()
response.forEach(item => setData([...data, item.data().name]))
}
useEffect(() => {
getDataFromFirebase()
},[])
data 被最新值覆蓋,而不是將所有值添加到數組中。
在setData
中使用回調
setData(prevState => ([
...prevState, item.data().name
]));
原因是添加項目所花費的時間非常少,這就是為什么在反映之前,它被覆蓋了。 您必須在 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() },[])
let response = await firestore.collection('someDatabase').get()
response.forEach(item => setData([...data, item.data().name]))
我不熟悉firestore
,但 promise 將被解決一次,你應該這樣做:
const dataToAdd = response.map(item => item.data().name)
setData(prevState => ([...prevState, ...dataToAdd])
每次調用setData
時,您都會重新渲染組件,並且您不應該在同步循環中執行此操作。
prevState
在這里是必要的,因為您正在異步 function 中工作。 從理論上講,如果您不在其他任何地方更改 state,則在使用帶有dataToAdd
的解決方案后,它應該可以在沒有它的情況下工作。
嘗試此觸發 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
會導致多次重新渲染,所以這里只觸發一次。
在您下面的代碼中,即使您稍后更改數據,數據的值也將始終為[]
。
const getDataFromFirebase = async () => {
let response = await firestore.collection('someDatabase').get()
response.forEach(item => setData([...data, item.data().name]))
}
這就是文檔所說的
function 組件(稱為 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)));
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.