首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Rtk查询未正确更新

Rtk查询未正确更新
EN

Stack Overflow用户
提问于 2022-08-19 04:46:06
回答 1查看 118关注 0票数 0

我正在使用firebase和rtkquery创建一个twitter克隆。我真的没有见过任何人使用带有firebase的rtkquery,我不得不使用承诺来解析数据,否则我就得不到数据。

代码语言:javascript
复制
return new Promise((resolve, reject) => {
            onSnapshot(q,(querySnapshot)=>{
              tweetsArr=querySnapshot.docs.map((doc)=>{
               console.log(doc.data());
                  return {id:doc.id,
                    ...doc.data()}
               })
               console.log(tweetsArr);
               resolve({data:tweetsArr});
            })})

我在我的apiSlice中使用这个函数来获取索引页面的帖子。问题是,如果我导航到配置文件页并刷新它,然后导航回索引页,我就会得到概要文件页的数据(getRetweetedPosts()),而不是(getPosts())。我consoled.log()并选中,我似乎在api片(getPosts())中使用正确的函数,但它解析了配置文件页(getRetweetedPosts())的先前数据,然后显示在索引页上,然后解析righ数据,我知道这是因为我使用的是console.log,但是它不仅仅是在刷新页面时显示出来的。

apiSlice getPosts

代码语言:javascript
复制
export const apiSlice = createApi({
  reducerPath:'api/apiSlice',
  baseQuery: fakeBaseQuery(),
  // The "endpoints" represent operations and requests for this server
  tagTypes: ['Posts','Users','RetweetPosts'],
  endpoints: builder => ({
    
    getPosts: builder.query<Posts[],void>({
      async queryFn(currUserId):Promise<any>{
        try{

          let currUserDocRef = doc(db,`users/${currUserId}`);
          let docData=(await getDoc(currUserDocRef)).data();
          //console.log(docData);
          let followingsArr=docData?.following??[];
          followingsArr.push(currUserId);
          //console.log(followingsArr);
          let tweetsArr: { }[]=[];
          const q=query(collection(db,'tweets'), where("creatorId", "in" , followingsArr))
          return new Promise((resolve, reject) => {
            onSnapshot(q,(querySnapshot)=>{
              tweetsArr=querySnapshot.docs.map((doc)=>{
            //   console.log(doc.data());
                  return {id:doc.id,
                    ...doc.data()}
               })
              // console.log(tweetsArr);
               resolve({data:tweetsArr});
            })})
        }

        catch(err:any){
          return{error:err} 
        }

    },providesTags: ['Posts']})

getRetweetedPosts

代码语言:javascript
复制
getRetweetedPosts: builder.query<Posts[],void>({
    async queryFn(currUserId):Promise<any>{
      try{

        let tweetsArr: { }[]=[];
        const q=query(collection(db,'tweets'), where("retweetedBy", "array-contains" , currUserId))
        return new Promise((resolve, reject) => {
          onSnapshot(q,(querySnapshot)=>{
            tweetsArr=querySnapshot.docs.map((doc)=>{
             //console.log(doc.data());
                return {id:doc.id,
                  ...doc.data()}
             })
             //console.log(tweetsArr);
             resolve({data:tweetsArr});
          })})
  
      }

      catch(err:any){
        return{error:err} 
      }

  },providesTags: ['RetweetPosts']}),
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-08-19 05:18:47

onSnapshot在这里是错误的工具。onSnapshot不会被调用一次,但是每次您获得新数据时,它都会继续运行并重新执行一次又一次。另一方面,您的queryFn只运行一次--而且您在那里创建的承诺只能解决一次。这意味着您确实创建了内存泄漏(数据将永远挂起,因为onSnapshot侦听器不会取消订阅),而没有任何好处。

您可能应该使用从火基获取数据一次的东西--比如getDoc。这也将更容易使用。

代码语言:javascript
复制
async queryFn(currUserId) {
      try{

        let tweetsArr: { }[]=[];
        const q=query(collection(db,'tweets'), where("retweetedBy", "array-contains" , currUserId))
        const querySnapshot = await getDocs(q)
        const data = querySnapshot.docs.map((doc)=> ({id: doc.id, ...doc.data()}))
        return { data }
      catch(err:any){
        return{error:err} 
      }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73411931

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档