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 работает так, как ожидалось, поэтому я не уверен, что я упускаю?
post.tags.map
выдаст ошибку при первом рендеринге вашего компонента, потому что в объекте по умолчанию, который вы передаете в useState, нет такого свойства/метода. Вы видите запрос axios в сетевом инспекторе? Если да, то какой ответ от вашего API? Если не считать очевидной проблемы, которую я указал в начале, это не то, с чем мы можем помочь не больше, чем вы предоставили.
сначала попробуйте поместить console.info внутри useEffect, но вверху, чтобы увидеть, действительно ли вы входите в него или нет.
В моей консоли не появляются запросы API, как и мои console.infos, независимо от того, где я их размещаю в useEffect. API отлично отвечает на идентичные запросы, сделанные из Postman или из браузера.
useEffect
запускается только при первом рендере, а затем при любом другом рендере, ЕСЛИ указанные зависимости изменились. Поскольку вы добавили туда пустой массив, они никогда не меняются.
Если вы хотите, чтобы useEffect
запускался снова при изменении идентификатора сообщения, вам нужно добавить id
в качестве зависимости для useEffect.
useEffect(() => {
....
}, [id, setPost]);
Кроме того, ваш post.tags
по-прежнему будет неопределенным, потому что данные поступают после того, как компонент завершил рендеринг, поэтому вы должны фактически проверить перед этим возвратом, есть ли у вас данные публикации, и если у вас нет данных публикации, чтобы вернуть нуль или скелет загрузки.
Я также пытался добавить зависимости, но проблема в том, что useEffect просто не работает при первом рендеринге или иным образом. Я поместил console.infos практически во все возможные места в хуке, но ни один из них не отображается, и на вкладке «Сеть» моей консоли нет запроса API. Это просто... Не работает. Также у меня сложилось впечатление, что компонент не будет отображаться, пока все в useEffect не будет разрешено? Во всяком случае, пока это не кажется проблемой.
Неважно, оказывается, что это было по существу проблемой. Проблема заключалась в том, что я забыл, что пустые объекты не являются ложными, поэтому мои попытки условного рендеринга на основе наличия «поста» работали неправильно. Задача решена. Ваше здоровье.
Вы пытались поместить console.info в начало useEffect, чтобы увидеть, входите ли вы или это просто пустой ответ выборки?