我正在用next.js开发一个博客网站。我有一个主页,这是一个服务器组件,但现在我想它改变为客户端组件,使我可以使它交互(集成分页)。
但是当我将代码转换为客户端组件时,它开始给我带来一些问题,例如浏览器窗口似乎不时地在本地主机打开时卡住。另外,API请求getPosts
方法没有被react的useState的setState函数存储,这有点奇怪。
下面给出的是以前的服务器组件的主页-
import { getCategoryPosts, getPosts } from '@/services'
import styles from '../../app/page.module.scss'
import PostCard from './PostCard'
type Props = { categorySlug?: string }
async function HomePagePosts({ categorySlug = '' }: Props) {
const { postsContainer } = styles
let posts
if (!categorySlug) {
posts = await getPosts()
} else {
posts = await getCategoryPosts(categorySlug)
}
return (
<section className={postsContainer}>
{posts.map((post) => (
<PostCard post={post} key={post.title}></PostCard>
))}
</section>
)
}
export default HomePagePosts
字符串
下面是新的客户端组件-
'use client'
import { useEffect, useState } from 'react'
import { getCategoryPosts, getPosts } from '@/services'
import styles from '../../app/page.module.scss'
import PostCard from './PostCard'
type Props = { categorySlug?: string }
function HomePagePosts({ categorySlug = '' }: Props) {
const [posts, setPosts] = useState([])
useEffect(() => {
async function setAllPosts() {
if (!categorySlug) {
setPosts(await getPosts())
} else {
setPosts(await getCategoryPosts(categorySlug))
}
}
setAllPosts()
}, [])
const { postsContainer } = styles
return (
<section className={postsContainer}>
{posts.map((post) => (
<PostCard post={post} key={post.title}></PostCard>
))}
</section>
)
}
export default HomePagePosts
型
上面的代码导致无限循环,导致窗口被卡住,并且状态呈现为空并且不更新。
但是如果我控制台记录getPosts()
方法,它会返回正确的内容,所以这个转换有问题。
编辑-
我注意到一些事-
return (
<section className={postsContainer}>
help
{posts?.map((post) => (
<div key={post.title}>{post.title}</div>
// <PostCard post={post} key={post.title}></PostCard>
))}
</section>
)
型
上面的代码给出了正确的post.title内容
但是如果我使用<PostCard/>
组件,那么只有它保持加载并进入无限循环,并且在posts状态下不显示任何内容。
PostCard组件是一个服务器组件,它是一个异步功能组件,所以这可能是问题吗?
这是明信片的代码--
import { postsType } from '@/utils/types/types'
import styles from '../../app/page.module.scss'
import moment from 'moment'
import Link from 'next/link'
import Image from 'next/image'
import { myPortfolioURL } from '@/services'
import LikeButton from '../buttons/LikeButton'
import CommentButton from '../buttons/CommentButton'
type Props = { post: postsType }
async function PostCard({ post }: Props) {
const {
postCard,
postImage,
title,
summary,
authorName,
authorInfo,
authorInfoContainer,
authorImage,
date,
icon,
userFeedbackContainer,
leftAlign,
rightAlign,
readTimeContainer,
postReactionSection,
} = styles
const authorId: string = (await myPortfolioURL(post.author.id)) || '/'
return (
<div className={postCard}>
<div className={authorInfoContainer}>
<Link
href={authorId}
className={authorInfo}
rel="noopener noreferrer"
target="_blank"
>
<div className={authorImage}>
<Image
src={post.author.photo.url}
style={{ objectFit: 'cover', borderRadius: '50%' }}
sizes="(max-width: 768px) 40px, (max-width: 1200px) 50px, 40px"
fill={true}
alt={post.author.name}
/>
</div>
<p className={authorName}>{post.author.name}</p>
</Link>
<div className={date}>
<p>{moment(post.createdAt).format('MMM DD, YYYY')}</p>
</div>
</div>
<Link href={`/post/${post.slug}`}>
<div className={postImage}>
<Image
src={post.featuredImage.url}
style={{ objectFit: 'cover', borderRadius: '.5rem' }}
fill={true}
alt={post.title}
/>
</div>
</Link>
<h1>
<Link href={`/post/${post.slug}`} className={title}>
{post.title}
</Link>
</h1>
<div className={summary}>{post.summary}</div>
<div className={postReactionSection}>
<div className={leftAlign}>
<div className={userFeedbackContainer}>
<LikeButton postId={post.id} />
<CommentButton postId={post.id} />
</div>
</div>
<div className={rightAlign}>
<div className={readTimeContainer}>{post.readTime} min read</div>
</div>
</div>
</div>
)
}
export default PostCard
型
1条答案
按热度按时间8dtrkrch1#
不能有异步效果。因此,您需要执行以下操作
字符串
更新:
根据更新后的问题。我注意到您正在使用服务器组件
PostCard
作为client component
的子组件。这就是错误的原因。客户端组件的所有子组件始终是客户端组件。因此,您应该从客户端组件中删除服务器端代码,并使其不异步。