React useEffect не запускает выборку при рендеринге компонента

#javascript #json #reactjs #fetch

Вопрос:

Я пытаюсь извлечь данные из JSON и сопоставить эти данные с компонентами, когда я комментирую компоненты, выборка успешно извлекает мои данные (через журнал консоли). Но когда у меня включены компоненты, приложение выходит из строя с ошибкой «Не удается прочитать свойство ‘root’ неопределенного».

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

Заранее приношу извинения за недостаток знаний, я только начал изучать React и очень зеленый.

 
import "./app.css";
import Legal from "../legal/Legal";
import BlogEntry from "./BlogEntry";

const Blog = ({ setSelectedLink }) => {
  const [items, setItems] = useState({});
  const fetchItems = async () => {
    const data = await fetch("https://api.jsonbin.io/v3/b/60bc11a492164b68bec13b15", {
      method: "GET",
      headers: {
        "X-Master-Key": "<API KEY HIDDEN FOR STACKOVERFLOW>",
      },
    });

    const items = await data.json();
    console.log(items);
    setItems(items);
  };
  useEffect(() => {
    fetchItems();
    window.scroll(0, 0);
    setSelectedLink(1);
  }, []);
  return (
    <>
      <div className="blog-page">
        <div className="blog-container">
          {items.record.root.map((entry) => {
            return (
              <BlogEntry
                key={entry.id}
                id={entry.id}
                title={entry.title}
                date={entry.date}
                body={entry.body}
              />
            );
          })}
        </div>
      </div>
      <Legal />
    </>
  );
};

export default Blog;
 

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

1. Видите ли вы какие-либо исключения в своей консоли… Я ожидаю, что начальный рендеринг вызовет исключение, такое как root или неопределенное, из-за вашего кода в элементах деталей jsx.records.root.. потому что в начальном рендеринге элементы будут там, но в нем не будет других свойств… Измените эту строку на «Товары»?. записи? .корень?.карта(

Ответ №1:

  1. Установите значение по умолчанию для items.record.root
 const [items, setItems] = useState({ record: { root: [] } });
 
  1. Передайте false в массив зависимостей вашего крючка эффекта, чтобы он был запущен один раз (и только один раз)
   useEffect(() => {
    fetchItems();
    window.scroll(0, 0);
    setSelectedLink(1);
  }, [false]);
 

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

1. поэтому я сделал то, что вы сказали, и получил бесконечный цикл (хотя компоненты отображались правильно). Но как только я удалил элементы из массива зависимостей в цепочке эффектов, все оказалось правильным, и никаких циклов, о которых можно было бы говорить!! 😀 setSelectedLink используется только для выделения кнопки «Текущие страницы» в заголовке. большое спасибо!

2. @RyanRigley Без проблем. Я отредактировал свой ответ, чтобы включить ваш конкретный вариант использования.

3. Да, это моя вина. Я fetchItems на секунду забыл, что items это обновление. 😅

Ответ №2:

Не могли бы вы, пожалуйста, попробовать использовать дополнительную цепочку ?. функция в этой части логики — элементы.запись.корень.карта