刷新页面时Array.length返回未定义

时间:2019-12-16 00:15:43

标签: javascript reactjs next.js

我有一个数组,当我检查长度(array.length)仅刷新页面时,该数组返回未定义。

如果我在chrome的新标签页中打开本地环境,则一切正常,我得到了数组的长度。仅刷新一次页面后,页面崩溃,并且出现以下错误: “ TypeError:无法读取未定义的属性'length'”。

我正在使用React,React的Context API(我是从上下文提供程序获取数组)和项目的Nextjs。我觉得这个问题与SSR有关,但我不确定。

这是与问题相关的相关代码。

上下文提供者

select t2.order_number
from table2 t2 left join
     table3 t3
     on t2.ORDER_DETAIL = t3.ORDER_DETAIL
group by t2.order_number
having count(t3.ORDER_DETAIL) = 0;

这是消耗上下文提供程序的代码

Cart.js

export function CartProvider(props) {
    let initializeState;
    if (typeof window !== 'undefined') {
        initializeState = JSON.parse(sessionStorage.getItem('cart'));
        if (initializeState === null) {
            initializeState = [];
        }
    }

    // Sets the cart
    const [ cart, setCart ] = useState(initializeState);
    return (
        <CartContext.Provider
            value={{ cart, setCart, checkCart, addItem, deleteItem, quantityIncrease, quantityDecrease }}
        >
            {props.children}
        </CartContext.Provider>
    );
}

非常感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

我认为您的错误与SSR有关。
如果使用SSR运行代码,则initializeState将收到未定义的内容。
但是initializeState应该如预期的那样是Array。
所以,我建议您更改代码:

// Change
    let initializeState;
    if (typeof window !== 'undefined') {
        initializeState = JSON.parse(sessionStorage.getItem('cart'));
        if (initializeState === null) {
            initializeState = [];
        }
    }

// To
    let initializeState = [];
    if (typeof window !== 'undefined' && sessionStorage.getItem('cart')) {
        initializeState = JSON.parse(sessionStorage.getItem('cart'));
    }

通过在调用JSON.parse时捕获错误,可以使代码更安全。但是,如果确保sessionStorage.getItem('cart')始终正确,则可以保留此代码。

答案 1 :(得分:0)

这是异步问题。变量在评估时未初始化,这就是您得到的方式:

  

“ TypeError:无法读取未定义的属性'length'”

尝试在使用提供程序时应用保护模式,如下所示:

import React, { Fragment, useContext } from 'react';
import ShoppingCart from '../components/ShoppingCart';
import { CartContext } from '../contexts/CartContext';
const cart = () => {
    const { cart } = useContext(CartContext);

    return (
        <Fragment>
            {(cart && (cart.length !== 0)) ? (
                <ShoppingCart />
            ) : (
                <div>
                    <h1>Your cart is empty</h1>
                </div>
            )}
        </Fragment>
    );
};

export default cart;

快速解释器:

cart && (cart.length !== 0)

翻译为:

  

当符号“购物车”的值为truthy时,

     

THEN返回表达式“ cart.length!== 0”的结果,

     

ELSE返回false

这样,您可以在运行时“保护”不安全的代码。