You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Context中useState([])返回undefined而非空数组问题

问题:React Context实现心愿单时数组返回undefined

我是React新手,参照此前正常运行的购物车Context代码复制实现心愿单功能,但调用wishlist数组时返回undefined,尽管已在心愿单Context中通过useState([])将其初始化为空数组。

心愿单相关代码

wishlistContext.js

import { createContext, useContext, useState } from "react";

const WishlistContext = createContext([]);

export const useWishlistContext = () => useContext(WishlistContext);

export const WishlistProvider = ({ children }) => {
  const [wishlist, setWishlist] = useState([]); // 已将wishlist初始化为空数组

  const value = {
    wishlist,
  };

  return (
    <WishlistContext.Provider value={value} displayName="wishlistContext">
      {children}
    </WishlistContext.Provider>
  );
};

Wishlist.jsx

import { useEffect, useState } from "react";
import { useWishlistContext } from "../context/wishlistContext";

export const Wishlist = () => {
  const { wishlist } = useWishlistContext();
  console.log(wishlist); // 此处返回undefined

  return (
    <div className="w-75 m-auto my-5">
      Something
    </div>
  );
};

正常运行的购物车参考代码

cartContext.js

import { createContext, useContext, useState } from "react";

const CartContext = createContext([]);

export const useCartContext = () => useContext(CartContext);

export const CartProvider = ({ children }) => {
  const [cart, setCart] = useState([]); // 已将cart初始化为空数组

  const removeProduct = (id) => {
    const newCart = cart.filter((product) => product.id !== id);
    setCart(newCart);
  };

  const addProduct = (item, qty) => {
    const element = cart.find((product) => product.id === item.id);

    if (!element) return setCart([...cart, { ...item, qty }]);

    const newCart = cart.map((product) => {
      if (product.id === item.id) {
        return { ...product, qty: product.qty + qty };
      }
      return product;
    });
    setCart(newCart);
  };

  const getTotal = () =>
    cart.reduce((acc, product) => acc + product.valor * product.qty, 0);

  const getCartQty = () => cart.reduce((acc, product) => acc + product.qty, 0);

  const emptyCart = () => setCart([]);

  const value = {
    cart,
    addProduct,
    removeProduct,
    getCartQty,
    getTotal,
    emptyCart,
  };

  return (
    <CartContext.Provider value={value} displayName="cartContext">
      {children}
    </CartContext.Provider>
  );
};

Cart.jsx

import { BsFillCartFill } from "react-icons/bs";
import { useEffect, useState } from "react";
import { addOrder } from "../api/orders";
import { updateManyProducts } from "../api/products";
import { useCartContext } from "../context/cartContext";
import Swal from "sweetalert2";

export const Cart = () => {
  const { getTotal, cart, emptyCart } = useCartContext();

  console.log(cart);

  if (cart.length <= 0)
    return (
      <div className="d-flex justify-content-evenly">
        <div className="text-center m-auto" style={{ fontWeight: 600 }}>
          <BsFillCartFill /> <br /> Su carrito esta vacío
        </div>
      </div>
    );

  const createOrder = async (e) => {
    e.preventDefault();
    const items = cart.map(({ id, nombre, qty, valor }) => ({
      id,
      nombre,
      qty,
      valor,
    }));

    let itemsAlert = "";

    for (let i = 0; i < items.length; i++) {
      itemsAlert +=
        "<b>Item:</b> " +
        items[i].nombre +
        "<br><b>Cantidad:</b> " +
        items[i].qty +
        " <b>Valor Unidad:</b> $" +
        items[i].valor +
        "<br><br>";
      console.log(itemsAlert);
    }

    const order = {
      buyer: { name, phone, email },
      items,
      fecha: newdate,
      estado: { orderState },
      total: getTotal(),
    };
    const { buyer, fecha, total } = order;

    const id = await addOrder(order);

    await updateManyProducts(items);
    emptyCart();

    Swal.fire({
      title: "Pedido Realizado",
      html: `El id de su compra es <b>"${id}"</b> <br> Fecha: ${fecha}<br><br> <b>Detalle de compra:</b><br> <br> <b>Comprador:</b> ${buyer.name} <br><br> ${itemsAlert}<br> <b>Total: $${total}</b>`,
      icon: "success",
      confirmButtonText: "OK",
    });
  };

  return (
    <div className="w-75 m-auto my-5">
      <h2 className="text-center my-5">
        <BsFillCartFill /> Carrito <BsFillCartFill />{" "}
      </h2>

      {cart.map((product) => (
        <div
          key={product.id}
          style={{
            display: "flex",
            gap: 50,
            height: 100,
            alignItems: "center",
            width: "70%",
            justifyContent: "space-evenly",
          }}
          className="m-auto"
        >
          <div>
            Producto :{" "}
            <b>
              <b>{product.nombre}</b>
            </b>
          </div>
          <div>
            Valor unitario :{" "}
            <b>
              <b>${product.valor}</b>
            </b>
          </div>
          <div>
            Cantidad :{" "}
            <b>
              <b>${product.qty}</b>
            </b>
          </div>
        </div>
      ))}
      <span
        style={{
          marginBottom: 50,
          textAlign: "center",
          width: "70%",
          fontSize: 20,
        }}
        className="mx-auto"
      >
        Total :{" "}
        <b>
          <b>${getTotal()}</b>
        </b>
      </span>
      <form style={{ display: "grid", gap: 10 }} className="mb-5">
        <span>Nombre</span>
        <input
          style={{ border: "1px solid black", height: 40 }}
          onChange={(e) => setName(e.target.value)}
        />
        <span>Telefono</span>
        <input
          type="phone"
          style={{ border: "1px solid black", height: 40 }}
          onBlur={(e) => validateInput(e.target.value, "phone")}
        />
        <span>Email</span>
        <input
          type="email"
          style={{ border: "1px solid black", marginBottom: 15, height: 40 }}
          onBlur={(e) => validateInput(e.target.value, "email")}
        />
        <span>Confirmar Email</span>
        <input
          style={{ border: "1px solid black", marginBottom: 15, height: 40 }}
          onBlur={(e) => checkEmail(e.target.value)}
        />
        <input type="submit" value="Enviar" onClick={createOrder} />
      </form>

      <div>
        {mailError}
        <br />
        {phoneError}
      </div>
    </div>
  );
};

排查原因与解决方法

核心问题:未用WishlistProvider包裹目标组件

购物车能正常运行,是因为你在应用入口(比如App.js/main.jsx)中用CartProvider包裹了Cart组件或整个应用。而心愿单的Wishlist组件没有被WishlistProvider包裹,导致useWishlistContext()拿到的是createContext的默认值(你这里默认值是[])。当你解构{ wishlist }时,数组没有wishlist属性,所以返回undefined。

解决步骤

  1. 打开应用入口文件(如App.js或main.jsx)
  2. 导入WishlistProvider,用它包裹Wishlist组件或整个应用:
import { WishlistProvider } from './context/wishlistContext';
import { Wishlist } from './components/Wishlist';

function App() {
  return (
    <WishlistProvider>
      {/* 其他组件 */}
      <Wishlist />
    </WishlistProvider>
  );
}

优化建议:统一Context默认值结构

将wishlistContext.js中的createContext默认值改为和Provider提供的value结构一致的对象,这样即使未包裹Provider,解构也不会得到undefined:

// 修改前
const WishlistContext = createContext([]);

// 修改后
const WishlistContext = createContext({ wishlist: [] });

内容的提问来源于stack exchange,提问作者Sebastian Sanjorge

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 10:55:21