简体   繁体   English

为什么 React 组件只渲染数组中的一项但遍历所有项?

[英]Why React component only renders one item in array once but iterates through all items?

I am stuck with a problem where I am building a blog with React and storing my blog posts in Firebase.我遇到了一个问题,我正在使用 React 构建博客并将我的博客文章存储在 Firebase 中。

The problem is that it goes through all items correctly in the useeffect function but when I want to render my items on the page it only shows one, the last item in my array.问题是它在 useeffect 函数中正确地遍历了所有项目,但是当我想在页面上呈现我的项目时,它只显示一个,即数组中的最后一个项目。

Here is my code:这是我的代码:

export default function Blog(props){
    const [blogPost, showBlogPost] = useState(null);
    const [blogPosts, setBlogPosts] = useState([]);

    useEffect(() => {
            db.collection('blogposts').get().then(posts => {
                console.log(posts.docs.length);
                posts.docs.forEach(post => {
                    blogPosts.push(post.data());
                    console.log(post.data());
                    
                    setBlogPosts([post.data()]);
                    console.log(blogPosts);
            })  
        })
    }, [])

    console.log(blogPosts);

    return(
        <div>  
            {CreateBlogPost()}
                {blogPosts.map(post => {                  
                        switch (blogPost) {
                            case post.id:
                                return( <BlogPost goBack={() => showBlogPost(null)} id={post.id} date={post.date} heading={post.heading} introduction={post.introduction} entry={post.entry} /> );   
                            case null: 
                                        return(
                                            <div> 
                                                 <ul className="blog-posts">
                                                     <div className="blog-post-item" onClick={() => showBlogPost(post.id)}>
                                                             <img src={Image}  alt="Girl in a jacket" width="400" height="200" />
                                                             <h1 id="blog-post-heading">{post.heading}</h1>      
                                                         <div className="time-stamp">
                                                             <p id="blog-post-publish-date"><ClockIcon /> <time dateTime={post.date}>{post.date}</time></p>
                                                         </div>
                                                     </div>
                                                 </ul>
                                            </div>
                                        );           
                            default: return null
                        }
                })}
        </div>
    )
}

Here is where I console log my array after pushing all my data from Firebase in my array which works fine:这是我将所有数据从 Firebase 推送到我的阵列后控制台记录我的阵列的位置,该阵列工作正常:

在此处输入图片说明

The code iterates through my code fine only within the useEffect function but when I console log blogPosts state array outside useEffect and try to render my array, it only renders the last item on the page.代码仅在 useEffect 函数中精细地遍历我的代码,但是当我在 useEffect 之外控制台 log blogPosts 状态数组并尝试呈现我的数组时,它只呈现页面上的最后一项。 在此处输入图片说明

Can someone please help me with this issue and guide me on how I should go forward here.有人可以帮我解决这个问题,并指导我如何在这里前进。 All help is appreciated.感谢所有帮助。

Thank you.谢谢你。

Three problems:三个问题:

  • Don't mutate state in React - you shouldn't be using .push on stateful arrays不要在 React 中改变状态 - 你不应该在有状态数组上使用.push
  • The setBlogPosts([post.data()]); setBlogPosts([post.data()]); only sets the new state array to a single item仅将新状态数组设置为单个项目
  • You're calling setBlogPosts for every element in the array, when you should only be calling it once, after processing all posts.docs您正在为数组中的每个元素调用setBlogPosts ,而在处理posts.docs所有posts.docs后,您应该只调用一次

Use采用

useEffect(() => {
    db.collection('blogposts').get().then(posts => {
        const newBlogPosts = [];
        posts.docs.forEach(post => {
            newBlogPosts.push(post.data());
        })
        setBlogPosts(newBlogPosts);
    })
    // .catch(handleErrors); // don't forget this part
}, [])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM