невозможно прочитать свойства undefined (чтение ‘map’)

Вопрос или проблема

Я пытаюсь получить данные из бэкенда и отобразить их на фронтенде моего приложения. Я использую fetch API, и CORS настроен правильно на бэкенде.

Когда компонент загружает данные, они не отображаются на фронтенде, поэтому я добавил console.log как способ отладки и понимаю, что мой

     'const data = await response.json()'
console.log(data)

обещание выполняется и отображается в консоли. Когда я также вывожу в консоль console.log( setData( data.dataProducts ));, я вижу undefined в консоли.

Я установил тернарный оператор в функции map, чтобы предотвратить сбой моего приложения, но перед этим в консоли появляется ошибка: невозможно прочитать свойства undefined (чтение ‘map’).

Мой бэкенд работает нормально, я протестировал его на Thunder Client, и он отображается. Я также протестировал в браузере, вставив этот маршрут: ‘http://localhost:8080/data’, и он тоже отображает мои данные в формате JSON на бэкенде.

Мои вопросы: Почему состояние set является undefined и почему свойства map являются undefined? Мне действительно нужна ваша помощь. Пожалуйста, простите меня за форматирование кода. Спасибо. Мои компоненты:

const Shopstore = () => {
  const [dataProducts, setData] = useState([]);

  const url = "http://localhost:8080/data";

  useEffect(() => {
    const fetchfunc = async () => {
      try {
        const response = await fetch(url);

        if (!response.ok) {
          throw new Error("проблемы с сетью, пожалуйста, подождите ");
        }
        const data = await response.json();
        console.log(data);
        console.log(setData(data.dataProducts));
      } catch (error) {
        console.log("ошибка", error);
      }
    };

    fetchfunc();
  }, []);

  return (
    <div className="Shopstore mt-5">
      <Container>
        <Row>
          <Col md={10} className="big mt-3">
            {dataProducts ? (
              dataProducts.map((product) => {
                return <Listings key={product._id} {...product} />;
              })
            ) : (
              <p>нет данных</p>
            )}
          </Col>
        </Row>
      </Container>
    </div>
  );
};

export default Shopstore;

//компонент-дочерний
const Listings = (products) => {
  const { image, heading, price, _id } = products;

  return (
    <div className="listings mt-3 mb-3">
      <Container>
        <Row>
          <Col md={4} id={_id}>
            <div className="card mx-auto" style={{ width: "250px" }}>
              <Card>
                <div className="image mx-auto ">
                  <Link to={`/shop/${products._id}`}>
                    <img
                      src={image}
                      alt=""
                      className="img-fluid"
                      style={{ width: "300px" }}
                    />
                  </Link>
                  <CardBody>
                    <div className="title">
                      <h5>{heading}</h5>
                    </div>
                    <div className="price">
                      <span>{price}</span>
                    </div>

                    <div className=" mx-auto">
                      <button className="mx-auto cartbutton">
                        Добавить в корзину
                      </button>
                    </div>
                  </CardBody>
                </div>
              </Card>
            </div>
          </Col>
        </Row>
      </Container>
    </div>
  );
};

export default Listings

Ответ или решение

Ошибка "cannot read properties of undefined (reading ‘map’)" вызвана тем, что вы пытаетесь вызвать метод map на переменной, которая равна undefined. Давайте разберем ваш код, чтобы понять, почему это происходит и как это исправить.

Анализ проблемы

Вы описали, что данные успешно загружаются из вашего API и отображаются в консоли, но при попытке установить эти данные в состояние с помощью setData(data.dataProducts) вы видите undefined. Это связано с тем, что setData не возвращает значение, поэтому результат console.log(setData(data.dataProducts)); всегда будет undefined. Функция setData просто обновляет состояние и не возвращает никаких данных.

Таким образом, нам нужно:

  1. Убедиться, что data.dataProducts действительно существует и имеет правильную структуру, прежде чем мы попытаемся установить его в состояние.
  2. Правильно обрабатывать ситуацию, когда данных нет (например, в случае ошибки или если данные не были загружены).

Возможное исправление

Следует инициировать состояние dataProducts как null или undefined, а затем проверить его перед вызовом map, чтобы избежать ошибки.

Вот пример того, как можно изменить ваш код:

const Shopstore = () => {
  const [dataProducts, setData] = useState(null); // изначально устанавливаем null

  const url = "http://localhost:8080/data";

  useEffect(() => {
    const fetchfunc = async () => {
      try {
        const response = await fetch(url);

        if (!response.ok) {
          throw new Error("network issues pls wait ");
        }
        const data = await response.json();
        console.log(data);
        setData(data.dataProducts || []); // если dataProducts нет, установить пустой массив
      } catch (error) {
        console.log("error", error);
      }
    };

    fetchfunc();
  }, []);

  return (
    <div className="Shopstore mt-5">
      <Container>
        <Row>
          <Col md={10} className="big mt-3">
            {dataProducts && dataProducts.length > 0 ? ( // проверяем на наличие данных
              dataProducts.map((product) => {
                return <Listings key={product._id} {...product} />;
              })
            ) : (
              <p>no data</p>
            )}
          </Col>
        </Row>
      </Container>
    </div>
  );
};

export default Shopstore;

Объяснение изменений

  1. Инициализация состояния: Вместо массива [], состояние dataProducts теперь инициализировано как null. Это позволяет легче проверять его наличие.
  2. Проверка данных: В JSX-коде мы добавили проверку на dataProducts && dataProducts.length > 0, чтобы убедиться, что данные загружены и это массив, прежде чем мы будем его маппить.
  3. Установка состояния: Установили setData(data.dataProducts || []), что означает, что если dataProducts нет, мы установим пустой массив, избегая дальнейших ошибок.

Таким образом, вы устраните ошибку "cannot read properties of undefined (reading ‘map’)" и гарантируете, что ваше приложение будет обрабатывать состояние корректно.

После применения этих изменений у вас должно работать корректное отображение данных и не возникнуть ошибок, связанных с отсутствующими свойствами.

Оцените материал
Добавить комментарий

Капча загружается...