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

Array.length is returning undefined when page is refreshed

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

如果我在 chrome 的新选项卡中打开我的本地环境,一切正常,并且我得到了数组的长度。只有在刷新页面一次后,页面崩溃并且出现以下错误: "TypeError: Cannot read property 'length' of undefined".

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

这是与问题相关的代码。

上下文提供程序

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>
    );
}

这是使用上下文提供程序的代码

Cart.js

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.length !== 0 ? (
                <ShoppingCart />
            ) : (
                <div>
                    <h1>Your cart is empty</h1>
                </div>
            )}
        </Fragment>
    );
};

export default cart;

非常感谢任何帮助!

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

"TypeError: Cannot read property 'length' of undefined"

像这样使用提供者时尝试应用保护模式:

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)

转换为:

WHEN symbol "cart" evaluates to a truthy value,

THEN return the result of the expression "cart.length !== 0",

ELSE return false

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

我认为您的错误与 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') 始终正确,则可以保留此代码。