Перехватчики React не позволяют мне отображать отдельные объекты после вызова Fetch - PullRequest
0 голосов
/ 09 мая 2020

Я вызываю стандартный файл JSON, используя выборку в проекте React Hooks. (я издеваюсь над сервером, используя JSON -Server для чтения локального json файла)

В моей основной функции я вызываю переменную и функцию, например любой обычный React Hook и устанавливаю его на пустой массив, потому что я вызываю данные API с помощью fetch.

let [items, setItems] = useState([]);

Затем я делаю свой фактический вызов fetch на свой фиктивный сервер

    const fetchItems = async () => {
        const url = "http://localhost:3002/learn";
        const response = await fetch(url);
        items = await response.json();
        setItems(items);
        console.log(items[0].title);
    }

Фактически, console.log(items[0].title) возвращает правильное значение.

Если бы я хотел отобразить все результаты, следующее могло бы работать.

{items.map((item) => 
   <img src={item.source} alt={item.title} title={item.title}  className="img-fluid mx-auto d-block" />
)}

Однако, как только я захочу отображать одно значение в моем возвращении, я получаю сообщение об ошибке: «TypeError: Невозможно прочитать свойство 'source' of undefined» Код, который я использую, чтобы сначала протестировать, точно такой же вещь как мой console.log из предыдущего.

<img src={items[0].source} alt={items[0].title} title={items[0].title}  className="img-fluid mx-auto d-block" />

Я пропустил важный шаг, который позволяет мне использовать полученную информацию в моем возвращении?

Если я если бы мои данные JSON были жестко закодированы для одного и того же компонента, это сработало бы. Я чувствую, что это как-то связано с выборкой. Я смотрел на этот вопрос, и он похож, но не одно и то же. Тоже крючки использую и тоже не топор ios. Невозможно отобразить данные после выборки

ОБНОВЛЕНИЕ: файл JSON выглядит примерно так:

{
    "learn": [
      {
        "id": 1,
        "title": "Angular JS",
        "source": "./images/logo-angular-js.png"
      },
      {
        "id": 2,
        "title": "Firebase",
        "source": "./images/logo-firebase.png"
      },
      {
        "id": 3,
        "title": "GraphQL",
        "source": "./images/logo-graphql.png"
      }
    ]
}

1 Ответ

2 голосов
/ 09 мая 2020

При первом рендеринге items имеет длину 0, поэтому items[0] будет undefined. Скорее всего, вы пытаетесь выполнить рендеринг до того, как загрузится этот первый элемент.

Проверьте, определено ли items[0], прежде чем пытаться получить доступ к items[0].source и т. Д.

function YourComponent() {
  const [items, setItems] = useState([]);

  useEffect(() => {
    fetchItems();
  }, []);

  const fetchItems = async () => {
    const url = "http://localhost:3002/learn";
    const response = await fetch(url);
    items = await response.json();
    setItems(items);
    console.log(items[0].title);
  }

  if (!items.length) {
    return null;
  }

  return (
    <img 
      src={items[0].source}
      alt={items[0].title}
      title={items[0].title}
      className="img-fluid mx-auto d-block" /> 
  );
}

На первом render, ничего не выводится. После вызова setItems компонент будет повторно визуализирован, и на этот раз (если были установлены элементы) он отобразит ваш элемент.

...