UseEffect вообще не работает при переходе на страницу с помощью React Router

App.js:

import React, { Fragment } from "react";
import Header from "./components/Header";
import PostList from "./components/PostList";
import Post from "./components/Post";
import TagList from "./components/TagList";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";

const App = () => {
  return (
    <Fragment>
      <Router>
        <Header />

        <Switch>
          <Route exact path = "/" component = {PostList} />
          <Route path = "/tags" component = {TagList} />
          <Route path = "/posts/:id" component = {Post} />
        </Switch>
      </Router>
    </Fragment>
  );
};

export default App;

Post.js:

import React, { useEffect, useState } from "react";
import Tag from "./Tag";
import { useParams } from "react-router-dom";
import axios from "axios";

const Post = () => {
  const { id } = useParams();
  const [post, setPost] = useState({});

  useEffect(() => {
    const fetchPost = async () => {
      try {
        const res = await axios.get(`/api/posts/${id}`);

        setPost(res.data);
      } catch (err) {
        console.error(err);
      }
    };
    fetchPost();
  }, []);

  return (
    <div>
      <h2>{post.title}</h2>
      <p>{post.text}</p>
      <div>
        {post.tags.map((tag) => (
          <Tag key = {tag._id} tag = {tag} />
        ))}
      </div>
    </div>
  );
};

export default Post;

Я пытаюсь запустить скелет простого сайта блога, но у меня проблемы с компонентом Post. При переходе к определенному сообщению с маршрутом «/posts/:id» useEffect, который должен получить сообщение из моего API, похоже, не запускается, и неизбежно я получаю ошибку «post.tags is undefined». Все остальное работает правильно — API отвечает на запросы от Postman, как и ожидалось, а «useParams» отлично извлекает идентификатор сообщения из URL-адреса — просто useEffect вообще не работает (console.infos тоже не отображается).

У меня не было проблем с этим в предыдущих проектах - на самом деле useEffect в компоненте TagList практически идентичен, а маршрут /tags работает так, как ожидалось, поэтому я не уверен, что я упускаю?

Вы пытались поместить console.info в начало useEffect, чтобы увидеть, входите ли вы или это просто пустой ответ выборки?

VersifiXion 11.12.2020 15:18
post.tags.map выдаст ошибку при первом рендеринге вашего компонента, потому что в объекте по умолчанию, который вы передаете в useState, нет такого свойства/метода. Вы видите запрос axios в сетевом инспекторе? Если да, то какой ответ от вашего API? Если не считать очевидной проблемы, которую я указал в начале, это не то, с чем мы можем помочь не больше, чем вы предоставили.
Jared Smith 11.12.2020 15:19

сначала попробуйте поместить console.info внутри useEffect, но вверху, чтобы увидеть, действительно ли вы входите в него или нет.

Sakshi 11.12.2020 15:24

В моей консоли не появляются запросы API, как и мои console.infos, независимо от того, где я их размещаю в useEffect. API отлично отвечает на идентичные запросы, сделанные из Postman или из браузера.

Nerbelwerzer 11.12.2020 15:44
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
4
2 198
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

useEffect запускается только при первом рендере, а затем при любом другом рендере, ЕСЛИ указанные зависимости изменились. Поскольку вы добавили туда пустой массив, они никогда не меняются.

Если вы хотите, чтобы useEffect запускался снова при изменении идентификатора сообщения, вам нужно добавить id в качестве зависимости для useEffect.

useEffect(() => {
  ....
}, [id, setPost]);

Кроме того, ваш post.tags по-прежнему будет неопределенным, потому что данные поступают после того, как компонент завершил рендеринг, поэтому вы должны фактически проверить перед этим возвратом, есть ли у вас данные публикации, и если у вас нет данных публикации, чтобы вернуть нуль или скелет загрузки.

Я также пытался добавить зависимости, но проблема в том, что useEffect просто не работает при первом рендеринге или иным образом. Я поместил console.infos практически во все возможные места в хуке, но ни один из них не отображается, и на вкладке «Сеть» моей консоли нет запроса API. Это просто... Не работает. Также у меня сложилось впечатление, что компонент не будет отображаться, пока все в useEffect не будет разрешено? Во всяком случае, пока это не кажется проблемой.

Nerbelwerzer 11.12.2020 15:42

Неважно, оказывается, что это было по существу проблемой. Проблема заключалась в том, что я забыл, что пустые объекты не являются ложными, поэтому мои попытки условного рендеринга на основе наличия «поста» работали неправильно. Задача решена. Ваше здоровье.

Nerbelwerzer 11.12.2020 17:13

Другие вопросы по теме