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 is being overridden with the latest value instead of adding all the values to the array.
Use the callback in setData
setData(prevState => ([
...prevState, item.data().name
]));
The reason is time taken to add item is very less thats why before reflecting, it got override. You have to use prevState in setData. Try this:
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]))
I'm not familiar with firestore
, but that promise will be resolved once, and you should do something like this instead:
const dataToAdd = response.map(item => item.data().name)
setData(prevState => ([...prevState, ...dataToAdd])
You are rerending component each time the setData
is being called and you shouldn't do it in a synced loop.
prevState
is necessary here because you are working in an asynchronous function. In theory, it should work without it after using a solution with dataToAdd
if you don't change the state anywhere else.
try this fire setState once but build the array before:
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()
},[])
firing setData
multiple times will cause multiple rerenders so here it's fire once.
In your code below the value of data will be always []
even if you change the data later.
const getDataFromFirebase = async () => {
let response = await firestore.collection('someDatabase').get()
response.forEach(item => setData([...data, item.data().name]))
}
This is what docs say about it
Mutations, subscriptions, timers, logging, and other side effects are not allowed inside the main body of a function component (referred to as React's render phase). Doing so will lead to confusing bugs and inconsistencies in the UI.
Its not a good idea to call setData in each loop. Populate an array and pass it to setData
once loop is complete.
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)));
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.