在这里,我试图从我的firebase显示所有数据到我的文章页面,但我得到了这种类型的错误:
TypeError:无法读取未定义的属性(阅读“map”)
这是我的Feed.js,它从firebase获取所有数据。
import { SparklesIcon } from '@heroicons/react/outline'
import React, { useEffect, useState } from 'react'
import Input from './Input'
import Post from './Post'
import { collection, onSnapshot, orderBy, query } from 'firebase/firestore';
import { db } from '@/firebase';
export default function Feed() {
const [posts, setPosts] = useState();
useEffect(
() =>
onSnapshot(
query(collection(db, "posts"), orderBy("timestamp", "desc")),
(snapshot) => {
setPosts(snapshot.docs);
}
),
[]
);
return (
<div className="xl:ml-[370px] border-1 border-r border-l border-r-gray-200 xl:min-w-[576px] sm:ml-[73px] flex-grow max-x-xl">
{/* Home nav */}
<div className="flex items-center py-3 px-3 sticky top-0 z-50 bg-white border-b border-gray-200">
<h2 className="text-lg sm:text-xl font-bold cursor-pointer">Home</h2>
<div className="hoverEffect flex items-center justify-center px-0 ml-auto w-9 h-9">
<SparklesIcon className="h-5" />
</div>
</div>
{/* Input */}
<Input />
{/* Post */}
{posts.map((post) => (
<Post key={post.id} posts={post} />
))}
</div>
)
}
字符串
并且,我希望所有数据都显示到Post.js中
下面是Post.js的代码
import { ChartBarIcon, ChatIcon, DotsHorizontalIcon, HeartIcon, ShareIcon, TrashIcon } from '@heroicons/react/outline'
import Image from 'next/image'
import React from 'react'
export default function Post({ post }) {
return (
<div className="flex p-3 cursor-pointer border-b border-gray-200">
{/* user-img */}
<Image
src={post.userImg}
alt="img-user"
className="w-11 h-11 rounded-full mr-4 object-cover"
width="50"
height="50"
>
</Image>
{/* right-side */}
<div>
{/* header */}
<div className="flex items-center justify-between">
{/* post-user-info */}
<div className="flex items-center justify-between space-x-2">
<h4 className="font-bold text-[15px] sm:text-[16px] hover:underline">{post?.name}</h4>
<span className="text-sm sm:text-[15px] text-gray-500">@{post?.username} •</span>
<span className="text-sm sm:text-[15px] text-gray-500 hover:underline">{post?.timestamp}</span>
</div>
{/* dot-icon */}
<DotsHorizontalIcon className="h-10 hoverEffect w-10 hover:bg-sky-100 hover:text-sky-500 p-2" />
</div>
{/* post-text */}
<p className="text-gray-800 text[15px sm:text-[16px] mb-2">{post?.text}</p>
{/* post-img */}
<Image
src={post?.image}
width="500"
height="500"
alt="post-img"
className="rounded-2xl mr-2 w-auto"
>
</Image>
{/* icons */}
<div className="flex justify-between text-gray-500 p-2">
<ChatIcon className="h-9 w-9 hoverEffect p-2 hover:bg-sky-100 hover:text-sky-500"/>
<TrashIcon className="h-9 w-9 hoverEffect p-2 hover:bg-red-100 hover:text-red-500"/>
<HeartIcon className="h-9 w-9 hoverEffect p-2 hover:bg-red-100 hover:text-red-500"/>
<ShareIcon className="h-9 w-9 hoverEffect p-2 hover:bg-green-100 hover:text-green-500"/>
<ChartBarIcon className="h-9 w-9 hoverEffect p-2 hover:bg-sky-100 hover:text-sky-500"/>
</div>
</div>
</div>
)
}
型
2条答案
按热度按时间2ledvvac1#
初始化
posts
如下:字符串
由于没有向
useState
传递任何值,因此posts
的初始值为undefined
。由于您随后在呈现代码中将其用作{posts.map((post) => (
,因此会得到错误消息。解决方案是使用代码可以处理的值初始化
posts
,如:型
现在
posts
最初将是一个空数组,这意味着您呈现的是一个空列表,而不是得到一个错误。bt1cpqcv2#
你会得到这个错误,因为你没有传递一个
initial state value
到你对useState
的调用中。当Feed
第一次呈现时,它试图对post
状态变量undefined
调用map
,直到useEffect可以运行您的onSnapshot
,将posts更新为(希望)数组。要解决这个问题,通过传递一个空数组作为初始状态值来更新对
useState
的调用:字符串
另外,我不知道
snapshot.docs
是否可以返回为undefined|null
,但确保posts值始终是一个数组是没有坏处的。考虑添加nullish coalescing operator(??)到您的呼叫
setPosts
像这样:型
我已经更新了您的代码片段以反映这些更改。
希望这对你有帮助!
型
更新:由于您正在查询集合,因此必须更新
setPosts
的方式,因为snapshot.docs
不能用作posts数组。型
这样做应该意味着您在
Post
组件中的代码不必更改您如何解析来自post
的值。您可以在Firestore文档中找到该模式的官方示例
下面是
for...of
语法的docs