简体   繁体   English

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

[英]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 is being overridden with the latest value instead of adding all the values to the array. data 被最新值覆盖,而不是将所有值添加到数组中。

Use the callback in setDatasetData中使用回调

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.您必须在 setData 中使用 prevState。 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:我不熟悉firestore ,但 promise 将被解决一次,你应该这样做:

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.每次调用setData时,您都会重新渲染组件,并且您不应该在同步循环中执行此操作。

prevState is necessary here because you are working in an asynchronous function. prevState在这里是必要的,因为您正在异步 function 中工作。 In theory, it should work without it after using a solution with dataToAdd if you don't change the state anywhere else.从理论上讲,如果您不在其他任何地方更改 state,则在使用带有dataToAdd的解决方案后,它应该可以在没有它的情况下工作。

try this fire setState once but build the array before:尝试此触发 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()
 },[])

firing setData multiple times will cause multiple rerenders so here it's fire once.多次触发setData会导致多次重新渲染,所以这里只触发一次。

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). function 组件(称为 React 的渲染阶段)的主体中不允许发生突变、订阅、计时器、日志记录和其他副作用。 Doing so will lead to confusing bugs and inconsistencies in the UI.这样做会导致 UI 中出现令人困惑的错误和不一致。

Its not a good idea to call setData in each loop.在每个循环中调用 setData 并不是一个好主意。 Populate an array and pass it to setData once loop is complete.一旦循环完成,填充一个数组并将其传递给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.

相关问题 在 useEffect React hook 中在不同时间实现多个 Firestore 调用 - Implementing multiple Firestore calls at different times within useEffect React hook 使用 Firestore 的 useEffect - useEffect with firestore useEffect 和 onAnimationEnd 回调在 state 中具有不同的值 - useEffect and onAnimationEnd callback have different values in state 在 useEffect 中无法访问 Redux 状态。 如何防止重复的 API 调用? - Redux state not accessible in useEffect. How to prevent repetitive API calls? 如何从 useEffect 访问组件的当前状态而不使其成为依赖项? - How to access current state of component from useEffect without making it a dependency? Firestore onSnapshot 通过 onEffect 中的 state 附加到阵列 - Firestore onSnapshot appending to array through state within onEffect 使用 vuex 并将新数据附加到 state 时对 firestore 数据进行分页 - Paginating firestore data when using vuex and appending new data to the state 更改状态而不覆盖反应中的其他值 - Change state without overriding other values in react 承诺全部进行四个 api 调用而不是两个 api 调用 - Promise all making four api calls instead of two api calls 反应useEffect state变量console.logs不同的值连续 - React useEffect state variable console.logs different values consecutively
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM