#javascript #reactjs #jsx
#javascript #reactjs #jsx
Вопрос:
Я работаю над веб-сайтом, который использует API от NYT, и я застрял, пытаясь отобразить всю информацию, которая у меня есть, для отображения необходимой информации (ссылки на изображения в формате JPG, ссылки на статьи, названия статей, даты статей).
У меня вся моя информация хранится в переменной с именем postNY и извлекается вся информация (из API) в эти массивы:
const [postNY, setPostNY] = useState({
images: [],
links: [],
titles: [],
sections: [],
dates: [],
summaries: []
})
// NOTE: OBJARR IS FROM API
// GET IMG
var imgs = []
for (var key in Object.entries(objArr)[3][1]) {
var obj = Object.entries(objArr)[3][1][key]
Object.entries(obj['media']).forEach(elem => {
imgs.push(elem[1]['media-metadata'][2].url)
}
)
}
// GET LINKS
var urls = []
Object.entries(objArr)[3][1].forEach(elem => urls.push(elem.url))
// GET TITLES
var titles = []
Object.entries(objArr)[3][1].forEach(elem => titles.push(elem.title))
// GET SECTION TAG
var sections = []
Object.entries(objArr)[3][1].forEach(elem => sections.push(elem.section))
// GET PUBLISHED DATE
var options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' };
var dates = []
Object.entries(objArr)[3][1].forEach(elem => {
var myDate = new Date(elem.published_date);
dates.push(myDate.toLocaleDateString("en-US", options))
})
// GET BRIEF SUMMARIES
var summaries = []
Object.entries(objArr)[3][1].forEach(elem => summaries.push(elem.abstract));
// setPostNY
setPostNY({
images: imgs,
links: urls,
titles: titles,
sections: sections,
dates: dates,
summaries: summaries
})
Тогда вот где возникает моя проблема. Я пытаюсь отобразить такую информацию в JSX:
const renderEverything = () => {
const renderImgs = postNY.images.map((img) => <img src={img}></img>)
const renderSummaries = postNY.summaries.map((summary) => <p className="desc">{summary}</p>)
const renderLinks = postNY.links.map((link) => <p>{link}</p>)
const renderTitles = postNY.titles.map((title) => <h2>{title}</h2>)
const renderDates = postNY.dates.map((date) => <p>{date}</p>)
const renderSections = postNY.sections.map((section) => <a href="#">{section}</a>)
return (
<div className="container">
{renderImgs}
{renderSummaries}
{renderLinks}
{renderTitles}
{renderDates}
{renderSections}
</div>
)
}
JSX:
return (
<div className="page-content">
{renderEverything}
</div>
)
Это ничего не возвращает на сайт. Я застрял на том, как реализовать отображение ВСЕХ этих вещей в массиве на сайте. Каждый массив упорядочен правильно, то, что я пытаюсь отобразить на сайте, это (в каждый из их собственных контейнеров):
1: postNY.images[0], postNY.links[0], postNY.titles[0], postNY.sections[0], postNY.dates[0], postNY.summaries[0]
2: postNY.images[1], postNY.links[1], postNY.titles[1], postNY.sections[1], postNY.dates[1], postNY.summaries[1]
И Т.Д…
Есть ли какие-либо подходы, которые я могу предпринять?
Вот полный код:
import React, {useState,useEffect} from 'react'
import '../PageContent/PageContent.css'
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'
import { faThumbsUp, faHeart} from '@fortawesome/free-solid-svg-icons'
const PageContent = (props) => {
const [postNY, setPostNY] = useState({
images: [],
links: [],
titles: [],
sections: [],
dates: [],
summaries: []
})
useEffect(() => {
fetch("https://api.nytimes.com/svc/mostpopular/v2/viewed/1.json?api-key=uCErKitNpdG7E7ma9rT0IxEGZ4xKs8Vw")
.then((res) => res.json())
.then((objArr)=>{
// GET IMG
var imgs = []
for (var key in Object.entries(objArr)[3][1]) {
var obj = Object.entries(objArr)[3][1][key]
Object.entries(obj['media']).forEach(elem =>
{
imgs.push(elem[1]['media-metadata'][2].url)
}
)
}
// GET LINKS
var urls = []
Object.entries(objArr)[3][1].forEach(elem => urls.push(elem.url))
// GET TITLES
var titles = []
Object.entries(objArr)[3][1].forEach(elem => titles.push(elem.title))
// GET SECTION TAG
var sections = []
Object.entries(objArr)[3][1].forEach(elem => sections.push(elem.section))
// GET PUBLISHED DATE
var options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' };
var dates = []
Object.entries(objArr)[3][1].forEach(elem =>
{
var myDate = new Date(elem.published_date);
dates.push(myDate.toLocaleDateString("en-US", options))
}
)
// GET BRIEF SUMMARIES
var summaries = []
Object.entries(objArr)[3][1].forEach(elem => summaries.push(elem.abstract));
setPostNY({
images: imgs,
links: urls,
titles: titles,
sections: sections,
dates: dates,
summaries: summaries
})
})
})
const renderEverything = () => {
const renderImgs = postNY.images.map((img) => <img src={img}></img>)
const renderSummaries = postNY.summaries.map((summary) => <p className="desc">{summary}</p>)
const renderLinks = postNY.links.map((link) => <p>{link}</p>)
const renderTitles = postNY.titles.map((title) => <h2>{title}</h2>)
const renderDates = postNY.dates.map((date) => <p>{date}</p>)
const renderSections = postNY.sections.map((section) => <a href="#">{section}</a>)
return (
<div className="container">
{renderImgs}
{renderSummaries}
{renderLinks}
{renderTitles}
{renderDates}
{renderSections}
</div>
)
}
return (
<div className="page-content">
{renderEverything}
</div>
)
}
export default PageContent
Комментарии:
1. Вы делаете это странным образом.
useState
находится в функциональном компоненте, который вы не можете вызватьsetPostNY
. Можете ли вы показать полный код функционального компонента. Где находитсяrenderEverything
по отношению кuseState
функции. находятсяrenderEverything
const [postNY, setPostNY]
ли они в одном и том же функциональном компоненте.objArr
Откуда это взялось. можете ли вы отредактировать свой пост, чтобы мы могли лучше понять, что происходит.2. ^^ @MrBrN197 высказывает обоснованную точку зрения. Нам нужно увидеть полный код. Однако, судя по тому, что вы показываете, renderEverything, похоже, не имеет доступа к postNY. Если render everything является функцией в рендеринге, это должна быть функция обратного вызова, и вам нужно определить массив зависимостей, передав ему postNY. Если функция не просматривает зависимости, она никогда не обновит эти значения зависимостей.
3. @MrBrN197 и Jason Я добавил полный код в конец сообщения
Ответ №1:
Убедитесь, что вы действительно вызываете функцию, которая возвращает содержимое. у вас {renderEverything}
это должно быть {renderEverything()}
return (
<div className="page-content">
{renderEverything()}
</div>
)
Также useEffect
укажите пустой массив зависимостей, чтобы он запускался один раз, иначе он будет выполняться непрерывно.
useEffect(() => {
// your fetch code
}, []) // add this
просто как примечание, использование Object.entries
делает код, который вы пишете, довольно подробным. javascript имеет множество функций, которые упрощают итерацию объектов и массивов. Вам не нужно использовать индексацию, когда вы можете произнести имя объекта.
вы можете преобразовать это
var imgs = []
for (var key in Object.entries(objArr)[3][1]) {
var obj = Object.entries(objArr)[3][1][key]
Object.entries(obj['media']).forEach(elem => {
imgs.push(elem[1]['media-metadata'][2].url)
})
}
к этому
let imgs = objArr.results.map( (entry) => entry.media?.[0]?.['media-metadata'][2].url )