Kar*_*kur 1 javascript reactjs next.js
我正在使用 next.js 开发一个博客网站。我有一个主页,它是一个服务器组件,但现在我希望它更改为客户端组件,以便我可以使其具有交互性(集成分页)。
但是,当我将代码转换为客户端组件时,它开始给我带来问题,例如浏览器窗口在打开 localhost 时似乎有时会卡住。还有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
Run Code Online (Sandbox Code Playgroud)
下面是新的客户端组件 -
'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
Run Code Online (Sandbox Code Playgroud)
上面的代码导致无限循环,导致窗口被卡住,并且帖子状态渲染为空并且不更新。
尽管如果我控制台记录该getPosts()方法,它会返回正确的内容,因此此转换存在问题。
编辑 -
我注意到一些事情——
return (
<section className={postsContainer}>
help
{posts?.map((post) => (
<div key={post.title}>{post.title}</div>
// <PostCard post={post} key={post.title}></PostCard>
))}
</section>
)
Run Code Online (Sandbox Code Playgroud)
上面的代码给出了正确的 post.title 内容
但如果我使用该<PostCard/>组件,则只有它继续加载并进入无限循环,并且不会在帖子状态中显示任何内容。
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
Run Code Online (Sandbox Code Playgroud)
你不能有异步效果。因此你需要执行以下操作
useEffect(() => {
getPosts().then(data => setPosts(data));
}, [])
Run Code Online (Sandbox Code Playgroud)
根据更新的问题。我注意到您正在使用服务器组件PostCard作为client component. 这就是错误的原因。客户端组件的所有子组件始终是客户端组件。
因此,您应该从客户端组件中删除服务器端代码,并使其不是异步的。
| 归档时间: |
|
| 查看次数: |
1647 次 |
| 最近记录: |