Firebase firestore:未处理的拒绝(RangeError):超出最大调用堆栈大小 [英] Firebase firestore : Unhandled Rejection (RangeError): Maximum call stack size exceeded

查看:72
本文介绍了Firebase firestore:未处理的拒绝(RangeError):超出最大调用堆栈大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

出于学习目的,开始使用 createAsyncThunk 玩耍,决定用firebase firestore实现购物车,但是在尝试在我的React应用中实现分页时遇到了问题.

在初始加载和后续加载(无限加载)期间,如何将最后一个可见状态返回到我的redux状态

我基于redux教程沙箱中的代码:

  • firestore中超出了最大调用堆栈大小

  • 然后我尝试在创建配置期间添加中间件serializableCheck,如下所示:

     导出默认的configureStore({middlleware:getDefaultMiddlleWare({serializableCheck:{//忽略动作类型ignoreActions:['RECEIVE_PRODUCTS/已完成']//忽略路径ignorePath:['products.last']}}),...//减速器代码}) 

    即使现在我已经消除了第一个错误,但超出调用堆栈的问题仍然存在.有谁知道为什么会这样吗?随意讨论是否有任何解决方法.谢谢.

    编辑2

    类似的方法在使用上下文时有效,但在使用redux时无效.我是否需要按照 Firebase未处理的错误中的建议将返回值包装在promise中RangeError:超出了最大调用堆栈大小?

    解决方案

    没有设法找到一种保存 lastVisible 的方法,但是我找到了一种解决方法,方法是仅跟踪将其保存为恢复状态来保存我的Firestore数据.

     <代码> export const fetchProducts = createAsyncThunk(types.RECEIVE_PRODUCTS,async(limit)=> {const resp =等待fire_base_product.firestore().collection(集合名称).orderBy('id').limit(限制)让result = resp.get().then((querySnapshot)=> {var lastVisible =限制-1;//只跟踪ID,这样我们就可以避免保存未序列化的编码const products = querySnapshot.docs.map((doc)=> {返回{... doc.data()}})返回 {产品:产品,lastVisible:lastVisible};})返回结果;} 

    当获取其他数据时,我们可以使用getState()来访问状态,如下所示:

     <代码> export const fetchMoreProducts = createAsyncThunk(types.LOAD_MORE_PRODUCTS,async(limit,{getState})=> {const last = getState().products.lastvar newProducts =等待firebase_product.firestore().collection('store_products').orderBy('id').startAfter(最后).limit(限制)const result = newProducts.get().then((querySnapshot)=> {var lastVisible = last + limit;const products = querySnapshot.docs.map((doc)=> {返回{... doc.data()}})返回 {产品:产品,lastVisible:lastVisible}})//从Firebase返回检索到的数据返回结果}) 

    但是这样做,我也可以一起跳过序列化检查配置.不知道这是否是正确的方法,但这就是我如何进行分页的方法.随时让我知道是否还有其他方法可以解决这个问题.

    Started playing around with createAsyncThunk for learning purpose, decided to implement a shopping cart with firebase firestore but I ran into problems when trying to implement pagination in my react app.

    How should I return the last visible state into my redux state during the initial load and subsequent load (infinite loading)

    I am basing on code from redux tutorial sandbox :https://codesandbox.io/s/github/reduxjs/redux-essentials-example-app/tree/checkpoint-3-postRequests/?from-embed, but instead of connecting to a fake api, I am using firebase firestore.

    Code to fetch product from firestore : ProductSlice.js

    const InitialState = {
       products : [],
       status: 'idle',
       error: null,
       last: null, //to hold lastVisible when fetching data from firestore
    }
    
    export const fetchProducts = createAsyncThunk(types.RECEIVE_PRODUCTS, async (limit) => {
       const resp = await fire_base_product.firestore()
          .collection(collection_name).orderBy('id').limit(limit)
    
       let result = resp.get().then((querySnapshot) => {
          const lastVisible = querySnapshot.docs[querySnapshot.docs.length - 1] //how set this to redux state
    
          const products = querySnapshot.docs.map((doc)=> {
             return { ...doc.data()}
          })
    
          return { 
             products: products, 
             lastVisible: lastVisible
          };
       })
    
       return result;
    }
    

    I am not quite sure on how to set this lastVisible data back into redux state, is it possible to do that with reference?

    #Edit:

    Tried to return both product list and last visible as an array and assign lastVisible in createSlice as stated below:

    const productSlice = createSlice({
       name:'products',
       initialState: 
       reducers: {},
       extraReducers:{
          [fetchProducts.fulfilled]: (state, action) => {
             state.products = state.products.concat(action.payload.products)
             state.last = action.payload.lastVisible // this causes call stack error
          }
    
       }
    });
    

    With the above coding, two error will be reported if I run react app,

    1. Trying to assign non serialize value into redux state

    2. Maximum call stack size exceeded in firestore

    I then tried to add middleware serializableCheck during create configuration as below:

    export default configureStore({
       middlleware: getDefaultMiddlleWare({
          serializableCheck: {
             //ignore action type
             ignoredActions : ['RECEIVE_PRODUCTS/fulfilled']
             // ignore path
             ignoredPath: ['products.last']
          }
       }),
       ... // reducer codes
    })
    

    Even though now I have dismissed the first error, call stack exceeded still exists. Does anyone knows why this is happening ? Feel free to discuss if there is any workaround on this. Thanks.

    Edit 2

    Similar approach works when using context but does not work when using redux. Do I need to wrap return in promise as suggested in Firebase Unhandled error RangeError: Maximum call stack size exceeded ?

    解决方案

    Did not managed to find a way to save lastVisible, but I found a workaround by just keeping track of the last retrieve id of my firestore data by saving it into redux state.

    export const fetchProducts = createAsyncThunk(types.RECEIVE_PRODUCTS, async (limit) => {
       const resp = await fire_base_product.firestore()
          .collection(collection_name).orderBy('id').limit(limit)
    
       let result = resp.get().then((querySnapshot) => {
          var lastVisible = limit - 1; //only keep track of ID so we can avoid saving un-serialize coded
    
          const products = querySnapshot.docs.map((doc)=> {
             return { ...doc.data()}
          })
    
          return { 
             products: products, 
             lastVisible: lastVisible
          };
       })
    
       return result;
    }
    

    And when during fetch of additional data we can then access the state by using getState() as below:

    export const fetchMoreProducts = createAsyncThunk(types.LOAD_MORE_PRODUCTS, async (limit, {getState}) => {
        const last = getState().products.last
    
        var newProducts = await firebase_product.firestore()
            .collection('store_products').orderBy('id')
            .startAfter(last).limit(limit)
    
        const result = newProducts.get().then((querySnapshot) => {
                var lastVisible = last + limit;
    
                const products = querySnapshot.docs.map((doc) => {
                    return { ...doc.data() }
                })
    
                return {
                    products : products, 
                    lastVisible: lastVisible
                }
            })
    
        // return retrieved data from firebase 
        return result
    })
    

    But doing this, I could skip the serialization check config all together as well. Not sure if this is the correct way, but this is how I got pagination working. Feel free to let me know if there is other way to approach this.

    这篇关于Firebase firestore:未处理的拒绝(RangeError):超出最大调用堆栈大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    相关文章
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆