#javascript #json #reactjs #next.js
#javascript #json #reactjs #next.js
Вопрос:
Я пытаюсь отобразить массив объектов и вернуть свойство ссылки как <li></li>
, но по какой-то причине ничего не возвращается:
import { useState, useEffect } from "react";
import { Config } from "../../config";
export default function Navbar() {
const [navs, setNavs] = useState();
const [mainNav, setMainNav] = useState();
const [links, setLinks] = useState();
useEffect(async () => {
const res = await fetch(`${Config.apiUrl}/navs`);
const data = await res.json();
setNavs(data);
// !!navs amp;amp; setMainNav(navs.map((x) => (x.name === "main-nav" ? x : null)));
}, []);
useEffect(() => {
!!navs amp;amp; setMainNav(navs.map((x) => (x.name === "main-nav" ? x : null)));
!!mainNav amp;amp; setLinks(mainNav.map((item) => item.link));
}, [navs]);
!!links amp;amp; console.log(links);
return (
<nav>
<ul>{!!links amp;amp; links.map((item) => <li>{item.link}</li>)}</ul>
</nav>
);
}
Результат моего console.log(links)
показывает следующий вывод:
[
{
_id: "5f975d6d7484be510af56903", link: "home", url: "/", __v: 0, id: "5f975d6d7484be510af56903"
},
{
_id: "5f975d6d7484be510af56904", link: "posts", url: "/posts", __v: 0, id: "5f975d6d7484be510af56904"
},
]
Я не понимаю, почему я могу получить доступ к link
свойству через item.link
.
PS Это начинает выглядеть слишком далеко от элегантного, у кого-нибудь еще есть идеи, как я могу это исправить?
Комментарии:
1. Можете ли вы поделиться тем, что вы получаете как «данные», т. е. Результат вызова api?
2. Можете ли вы записать в консоль свой
data
и добавить его сюда. Это поможет нам отладить проблему.
Ответ №1:
Проблема здесь,
useEffect(() => {
!!navs amp;amp; setMainNav(navs.map((x) => (x.name === "main-nav" ? x : null)));
!!mainNav amp;amp; setLinks(mainNav.map((item) => item.link));
}, [navs]);
Проблема в том, что вы используете mainNav из состояния сразу после установки значения в состоянии в приведенном выше useEffect . Он не ожидает обновления состояния, а затем принимает результат. Здесь у вас есть два варианта,
Либо объявить другой эффект использования, подобный этому,
useEffect(() => {
!!navs amp;amp; setMainNav(navs.map((x) => (x.name === "main-nav" ? x : null)));
}, [navs]);
useEffect(() => {
!!mainNav amp;amp; setLinks(mainNav.map((item) => item.link));
}, [mainNav]);
Или вы можете сначала сохранить mainNav в переменной. Вот так,
useEffect(() => {
let mainNavData = [];
if(!!navs) {
mainNavData = navs.map((x) => (x.name === "main-nav" ? x : null));
setMainNav(mainNavData);
setLinks(mainNavData.map((item) => item.link));
}
}, [navs]);
Комментарии:
1. Итак, я попробовал первый вариант : ничего не передавалось на страницу, и массив
console.log
регистрировался 6 раз (вместо 3). Я попробовал второй вариант , который вы дали: ничего не отображалось на странице, иconsole.log
3 раза регистрировался пустой объект. Ни один из них не работал.2. Возникла проблема со 2-м вариантом. Это должно вызвать некоторую ошибку. Попробуйте еще раз. Обновлено 2-е решение.
3. Итак, второй вариант теперь возвращает a
console.log
3 раза, дважды с пустым массивом и один раз с заполненным массивом. Он также ничего не отображал на странице.