Доступ к данным, установленным React Hook в функции

avatar
Andrew Ho
9 августа 2021 в 06:11
46
2
0

Я немного новичок в React. Я пытаюсь сделать запрос GET от конечной точки REST API, который должен вернуть следующий JSON:

{
    "author": "aqho",
    "title": "Second post!",
    "slug": "second-post",
    "body": "Let's see if things get updated in the database like the slug",
    "comments_list": [
        {
            "author": "aqho",
            "body": "it works!",
            "slug": "7213569934952552711-3"
        },
        {
            "author": "bobglu",
            "body": "how are you just so classically handsome",
            "slug": "2029512273124111200-4"
        }
    ]
}

Для запроса API я использую следующий код:

const PostDetailPage = (props) => {
    const [post, setPost] = useState({});

    useEffect(() => {
        const slug = props.match.params.slug;
        const fetchData = async () => {
            try {
                const res = await API.get(`posts/${slug}`);
                setPost(res.data);
            }
            catch (err) {
                console.log(err)
            }
        };
        
        fetchData();
    }, []);
...
}

Я хочу создать функцию, которая возвращает список комментариев из JSON. Моя первоначальная попытка была следующей:

const renderComments = () => {
        return post.comments_list.map(item => (
          <li 
            key={item.slug}
          >
            {item.body}
          </li>
        ));
      };

Однако выдает ошибку TypeError: Cannot read property 'map' of undefined. Глядя в интернет, кажется, что проблемы большинства людей можно решить, установив значение по умолчанию для пустого словаря, но я уже сделал это в своем хуке React. Я очень смущен тем, почему posts.comments_list не определен. Я также заметил, что попытка записать заголовок сообщения с помощью console.log(post.title) также дает мне undefined. Я немного смущен, почему это так, потому что следующий код может прекрасно извлекать значения из post:

const PostDetailPage = (props) => {
...
    return (
            <div id='post-details-page'>
                <div id='post-details'>
                    <h1>{post.title}</h1>
                    <h4>Published on: {post.published_on}</h4>
                    <h4>Last edited: {post.last_edited}</h4>
                    <p> {post.body} </p>
                </div>
            </div>
        );
};

export default PostDetailPage;
Источник

Ответы (2)

avatar
gu mingfeng
9 августа 2021 в 06:19
2
const renderComments = () => {
        return post.comments_list?.map(item => (
          <li 
            key={item.slug}
          >
            {item.body}
          </li>
        ));
      };

при первом рендеринге post = {}, post.comments_list не определен.

avatar
Divyesh Kanzariya
9 августа 2021 в 06:14
0

нужно просто добавить объект проверки post и post.comments_list т.к. изначально он пустой

const renderComments = () => {
        return post && post.comments_list &&post.comments_list.map(item => (
          <li 
            key={item.slug}
          >
            {item.body}
          </li>
        ));
      };