【问题标题】:How can I render multiple components interpolating JSX?如何渲染多个插入 JSX 的组件?
【发布时间】:2021-02-12 15:34:27
【问题描述】:

我正在开发一个使用 NYT 的 API 的网站,但我一直在尝试呈现我必须显示的所有信息以显示所需的必要信息(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

【问题讨论】:

  • 你正在以一种奇怪的方式处理这件事。 useState 在功能组件中,那么您不能调用 setPostNY。你能显示功能组件的完整代码吗? renderEverything 相对于 useState 函数在哪里。 renderEverythingconst [postNY, setPostNY] 是否在同一个功能组件中。 objArr 是什么,从哪里来的。您可以编辑您的帖子,以便我们更好地了解正在发生的事情。
  • ^^ @MrBrN197 提出了一个有效的观点。我们需要查看完整的代码。根据您所展示的内容,renderEverything 似乎无法访问 postNY。如果渲染一切都是渲染中的一个函数,它需要是一个回调函数,你需要定义一个依赖数组,将 postNY 传递给它。如果函数没有监视依赖项,它永远不会更新这些依赖项值。
  • @MrBrN197 和 Jason 我已将完整代码添加到帖子底部

标签: javascript reactjs jsx


【解决方案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 )

【讨论】:

    猜你喜欢
    • 2021-05-17
    • 2018-03-07
    • 2018-04-08
    • 2020-05-27
    • 2022-07-18
    • 2020-10-12
    • 2020-06-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多