Mukyuu Ответов: 1

Ошибка типа: не удается прочитать свойство 'map' null - react JS


Недавно я хотел сделать функционал, где если пользователь добавил товар в корзину, то он будет храниться в локальном хранилище.

Я попытался реализовать это в своей жизни. Продукта.jsx файл. И это код, который я использовал, чтобы сделать продукт, хранящийся в локальном хранилище:
const saveLocalProducts = () => {
    localStorage.setItem("products", JSON.stringify(products));
  };
  const getLocalProducts = () => {
    if (localStorage.getItem("products") === null) {
      localStorage.setItem("products", JSON.stringify([]));
    } else {
      let productLocal = JSON.parse(localStorage.getItem("games"));
      setProducts(productLocal);
    }
  };
  useEffect(() => {
    getLocalProducts();
    saveLocalProducts();
  }, []);

Примечание: это также происходит после функции addToCart (), где находятся все переменные.
Потом я сэкономил и вот что получил:

Изображение Ошибки

Вот где ошибка говорит, что она находится:
return (
    <div className="products">
      <h1 className="big-text">Games</h1>

      {/* Cards */}
      <div className="products">
        <ul className="flex cards">
          {products.map((product, index) => (
            <li key={index}>
              <h2>{product.name}</h2>
              <div className="space3"></div>
              <img src={product.image} alt={product.name} />
              <div className="space"></div>
              <div className="buy-product">
                <button onClick={() => (window.location.href = product.link)}>
                  Buy
                </button>
              </div>
              <h4>${product.cost}</h4>
              <div className="cart-container">
                <div className="space2"></div>
                <div className="product-icon">
                  <a className="cart" onClick={() => addToCart(product)}>
                    <FaCartPlus />
                  </a>
                </div>
              </div>
            </li>
          ))}
        </ul>
      </div>
    </div>
  );

Возможно, полезный совет: когда вы очищаете хранилище и обновляете вкладку, она показывает страницу игр, и все работает нормально; но когда вы снова обновите вкладку, она покажет ошибку.

Помощь очень ценится!

EDIT: кроме того, это мой полный обновленный файл, который находится на GitHub:

import React, { useState, useEffect } from "react";
import { toast } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
import { FaCartPlus } from "react-icons/fa";

toast.configure();

function Products({ setCart, cart }) {
  const [products, setProducts] = useState([
    {
      name: "Cyber Punk 2077",
      cost: null,
      image: "https://images.igdb.com/igdb/image/upload/t_cover_big/co1rft.jpg",
      link: "https://www.cyberpunk.net/us/en/pre-order",
    },
    {
      name: "Fall Guys",
      cost: 28.95,
      image: "https://images.igdb.com/igdb/image/upload/t_cover_big/co2fq7.jpg",
      link:
        "https://store.steampowered.com/app/1097150/Fall_Guys_Ultimate_Knockout/",
    },
    {
      name: "Among Us",
      cost: 7.5,
      image: "https://images.igdb.com/igdb/image/upload/t_cover_big/co1uaf.jpg",
      link: "https://store.steampowered.com/app/945360/Among_Us/",
    },
    {
      name: "A Monster's Expedition",
      cost: 28.95,
      image: "https://images.igdb.com/igdb/image/upload/t_cover_big/co2eop.jpg",
      link: "https://store.steampowered.com/app/1052990/A_Monsters_Expedition/",
    },
    {
      name: "Halo Infinite",
      cost: null,
      image: "https://images.igdb.com/igdb/image/upload/t_cover_big/co2dto.jpg",
      link: "https://store.steampowered.com/app/1240440/Halo_Infinite/",
    },
    {
      name: "Rocket League",
      cost: null,
      image: "https://images.igdb.com/igdb/image/upload/t_cover_big/co2hnd.jpg",
      link:
        "https://store.steampowered.com/app/252950/Rocket_League/?curator_clanid=11855704",
    },
    {
      name: "The Falconeer",
      cost: null,
      image: "https://images.igdb.com/igdb/image/upload/t_cover_big/co2e3l.jpg",
      link: "https://store.steampowered.com/app/1135260/The_Falconeer/",
    },
    {
      name: "Genshin Impact",
      cost: null,
      image: "https://images.igdb.com/igdb/image/upload/t_cover_big/co1ltz.jpg",
      link: "https://genshin.mihoyo.com/en",
    },
  ]);
  const addToCart = (product) => {
    let newCart = [...cart];
    let itemInCart = newCart.find((item) => product.name === item.name);

    if (itemInCart) {
      toast.error(`${product.name} is already in cart`, {
        autoClose: 1300,
      });
    } else {
      itemInCart = {
        ...product,
        quantity: 1,
      };

      toast.success(`${product.name} has been added to cart`, {
        autoClose: 1200,
      });

      newCart.push(itemInCart);
    }

    setCart(newCart);
  };
  const item = useState([]);

  const saveLocalProducts = () => {
    localStorage.setItem("games", JSON.stringify(item));
  };
  const getLocalProducts = () => {
    if (localStorage.getItem("games") === null) {
      localStorage.setItem("games", JSON.stringify([]));
    } else {
      let productLocal = JSON.parse(localStorage.getItem("games"));
      setProducts(productLocal);
    }
  };
  useEffect(() => {
    getLocalProducts();
    saveLocalProducts();
  }, []);

  if (item) {
    return (
      <div className="products">
        <h1 className="big-text">Games</h1>

        {/* Cards */}
        <div className="products">
          <ul className="flex cards">
            {products.map((product, index) => (
              <li key={index}>
                <h2>{product.name}</h2>
                <div className="space3"></div>
                <img src={product.image} alt={product.name} />
                <div className="space"></div>
                <div className="buy-product">
                  <button onClick={() => (window.location.href = product.link)}>
                    Buy
                  </button>
                </div>
                <h4>${product.cost}</h4>
                <div className="cart-container">
                  <div className="space2"></div>
                  <div className="product-icon">
                    <a className="cart" onClick={() => addToCart(product)}>
                      <FaCartPlus />
                    </a>
                  </div>
                </div>
              </li>
            ))}
          </ul>
        </div>
      </div>
    );
  }
}

export default Products;


Что я уже пробовал:

Я попытался переименовать имя ключа и поискать его без каких-либо решений.

Хотя я действительно видел вопрос, который относится к этому виду, а именно этот вопрос на Reddit...хотя это не очень помогло, так как вам нужно было значение по умолчанию, а поскольку это касается продуктов, я не могу иметь значение по умолчанию, потому что это должно было бы означать, что игра уже находится в корзине, прежде чем вы даже нажмете кнопку Добавить в корзину. Если вы понимаете, что я имею в виду?

Sandeep Mewara

Не смотрите карту в вашем коде выше. Как можно улучшить вопрос и обновить ту часть, где вы используете карту.

Mukyuu

Ой, извините! Я думал, что уже положил это туда...

1 Ответов

Рейтинг:
0

Sandeep Mewara

Как вы определили products до сих пор не ясно. Я могу только догадываться, что он инициализирован как null в вашем компоненте и это вызывает ошибку.

map работает только на массивах. Итак, проверьте, что продукты определены массивом, прежде чем делать на нем карту.
Попробуй это и увидишь:

if(products)
{
  products.map((product, index) => (
    <li key={index}>
      <h2>{product.name}</h2>
      <div className="space3"></div>
      <img src={product.image} alt={product.name} />
      <div className="space"></div>
      <div className="buy-product">
        <button onClick={() => (window.location.href = product.link)}>
          Buy
        </button>
      </div>
      <h4>${product.cost}</h4>
      <div className="cart-container">
        <div className="space2"></div>
        <div className="product-icon">
          <a className="cart" onClick={() => addToCart(product)}>
            <FaCartPlus />
          </a>
        </div>
      </div>
    </li>
  ))}
}

Если это не решит проблему, посмотрите на другие возможные причины здесь и устраните неполадки: React - не удается прочитать свойство 'map' undefined[^]


Mukyuu

@SandeepMewara хорошо, я сделал это так:

<ul className="flex cards">
          {if (products) {
            products.map((product, index) => (
            <li key={index}>
              <h2>{product.name}</h2>
              <div className="space3"></div>
              <img src={product.image} alt={product.name} />
              <div className="space"></div>
              <div className="buy-product">
                <button onClick={() => (window.location.href = product.link)}>
                  Buy
                </button>
              </div>
              <h4>${product.cost}</h4>
              <div className="cart-container">
                <div className="space2"></div>
                <div className="product-icon">
                  <a className="cart" onClick={() => addToCart(product)}>
                    <FaCartPlus />
                  </a>
                </div>
              </div>
            </li>
          ))
          }}
        </ul>

А там написано: "выражение ожидаемое".

Sandeep Mewara

Это не выход. Вы дали фрагмент, так что я обновил его. очевидно, что в том, чем вы поделились, есть еще один код. (ваш код не будет просто ul-тегами, их будет больше.)

Пожалуйста, отрегулируйте логику - вам нужно проверить, что продукты являются нулевыми. Или определите фиктивное/пустое значение.

Mukyuu

О...извини, я думал, что просто должен поделиться той частью, где был код. Теперь я обновил вопрос.

Sandeep Mewara

Вы вернетесь только в том случае, если продукты там есть, или же не войдете в этот код.

если(продукты){
// ваш текущий код возврата
вернуть....
}

Mukyuu

Я попробовал это сделать:

Скрыть   Расширять   скопировать код

if (item) {    return (      <div className="products">        <h1 className="big-text">Games</h1>        {/* Cards */}        <div className="products">          <ul className="flex cards">            {products.map((product, index) => (              <li key={index}>                <h2>{product.name}</h2>                <div className="space3"></div>                <img src={product.image} alt={product.name} />                <div className="space"></div>                <div className="buy-product">                  <button onClick={() => (window.location.href = product.link)}>                    Buy                  </button>                </div>                <h4>${product.cost}</h4>                <div className="cart-container">                  <div className="space2"></div>                  <div className="product-icon">                    <a className="cart" onClick={() => addToCart(product)}>                      <FaCartPlus />                    </a>                  </div>                </div>              </li>            ))}          </ul>        </div>      </div>    );  }


И это все еще не работает. (Кстати, этот код находится после useEffect ().)

Mukyuu

@SandeepMewara причина, по которой я не хотите определить фиктивное / пустое значение, потому что переменная products содержит все продукты. Если не...Я делаю это не в том файле. Возможно, мне придется поместить это в Cart.jsx, но функция, в которой вы добавляете продукт в корзину, находится в Products.jsx...