Ошибка типа: Не удается прочитать свойство «url» неопределенного при загрузке изображения

#reactjs #foreach #jsx

Вопрос:

Получаю ошибку при попытке сопоставить и массив строк URL-адресов из monogo atlas, эти URL-адреса взяты из google firebase, которую я вручную создал в atlas и вставил URL-адреса в виде строк. Я прокомментировал функцию карты, чтобы узнать, не было ли это причиной того, что URL-адрес не определен, но это не так. Чтобы указать свойство во вложенных данных, я использовал «res.data.data.url», который должен работать, но не работает. У меня есть снимок экрана этого массива с консоли ниже. Что странно, так это то, что до того, как данные были утешены как объект данных, вложенный в другой объект данных, и URL-адрес, вложенный в этот объект, теперь я вижу только объект массива.

Чтобы получить массив в консоли, я сделал res.data. Затем я попытался получить URL-адрес с помощью: «res.url» и «res.data.url», а затем «url», и URL-адрес по-прежнему не определен.

Я протестировал контроллер в экспресс-узле, утешил ответ и вернул свой массив в полном объеме, я просто получаю статус 304 в терминале, так что моя теория заключается в том, что проблема находится на переднем конце в react.

Может ли кто-нибудь помочь мне с этой ошибкой в решении неопределенного, поэтому я не могу видеть свои изображения?

Вот код

 const Gallery = () => {

  const [url, setUrl] = useState([]);
  const history = useHistory();

  const loadImage = async () => {
    try {
      let res = await axios
      .get("http://localhost:5000/geturls");
     // console.log(res.data)
      setUrl(res.data.data.url);
    } catch (error) {
      console.log(error);
    }
  };

  useEffect(() => {
  // function to check login token
    loadImage();
  });
  // },[]);

  return (
    <div className="postverse">
      <Container className="mt-5 ml-auto mr-auto">
        <div className="mb-4 mt-4">
          <Navi />
        </div>
        <h1 className="text-center">
          ShareVerse
          <span className="text-success"> Gallery</span>
        </h1>
        <Row className="d-flex align-items-center justify-content-center">
          <Col className="mb-2" xs="12" lg="3">
            <Nav.Link href="/waterfall">
              {url.map((url) => (
                <Image alt="" className="img-fluid" src={`${url}`} thumbnail  />
              ))}
            </Nav.Link>
          </Col>
        </Row>
      </Container>
    </div>
  );
};

export default Gallery; 

введите описание изображения здесь

Комментарии:

1. можете ли вы показать нам структуру ответа, полученную от axios?

Ответ №1:

На основе вашей консоли.снимок экрана журнала данные ответа axios представляют собой массив объектов, поэтому, чтобы иметь только массив URL-адресов, вам нужно сопоставить его следующим образом:

  const loadImage = async () => {
    try {
      let res = await axios
      .get("/data.json");
      console.log(res.data)
      setUrl(res.data.map(d=>d.url));
    } catch (error) {
      console.log(error);
    }
  };
 

и если вам нужно получить данные только во время рендеринга, передайте пустой массив для использования зависимостей эффекта:

   useEffect(() => {
  // function to check login token
    loadImage();

  },[]);
 

в ответ я бы изменил переменную с именем URL, чтобы избежать путаницы с вашим списком, что-то вроде:

  {url.map((urlData) => (
            <Image alt="" className="img-fluid" src={urlData} thumbnail  />
              ))}
 

вам не нужно использовать ${url} , вы можете напрямую передавать urlData, потому что это тип строки
Обновить
Если вам нужен совет, я бы сохранил массив объектов из res.data, потому что вам нужно будет передать ключ в <Image alt="" className="img-fluid" src={urlData} thumbnail />

поэтому я бы переименовал свою переменную состояния чем-то вроде данных и сделал что-то вроде:

 const Gallery = () => {

  const [data, setData] = useState([]);


  const loadImage = async () => {
    try {
      let res = await axios
      .get("/data.json");
      console.log(res.data)
      setData(res.data);
    } catch (error) {
      console.log(error);
    }
  };

  useEffect(() => {
  // function to check login token
    loadImage();

  },[]);

    return (
    <div className="postverse">
      <Container className="mt-5 ml-auto mr-auto">
        <div className="mb-4 mt-4">
          <Navi />
        </div>
        <h1 className="text-center">
          ShareVerse
          <span className="text-success"> Gallery</span>
        </h1>
        <Row className="d-flex align-items-center justify-content-center">
          <Col className="mb-2" xs="12" lg="3">
            <Nav.Link href="/waterfall">
              {data.map((image) => (
                <Image key={image._id} alt={image.name} className="img-fluid" src={image.url} thumbnail  />
              ))}
            </Nav.Link>
          </Col>
        </Row>
      </Container>
    </div>
  );
};

export default Gallery;