所以我正在制作一个小博客文章项目,在这个项目中我调用了状态“mainblog”和“relatedBlogs”的 api。当我尝试将 mainBlog 传递给组件“Post”时,它在重新加载时给我一个错误,说我的 mainBlog 为空(这是初始状态)。但它在重新渲染(而不是重新加载)时工作得很好。我猜这是因为 setState 函数是异步的,它更新 mainBlog 太晚了。
我的问题是:为什么放置条件渲染可以解决这个问题?我已经放了:
mainBlog && (
<div>
<Post post={mainBlog} />
<h2 className='py-4 text-3xl font-bold'>Related Blogs</h2>
<div className='flex flex-col gap-y-7'>
{relatedBlogs.map((blog) => (
<Post key={blog.id} post={blog} />
))}
</div>
</div>
)
它以某种方式解决了这个问题。这是为什么?为什么它在异步 setState 函数完成后检查条件。
主要代码:
import { useContext, useEffect, useState } from 'react'
import BackButton from '../components/BackButton'
import Header from '../components/Header'
import { useLocation } from 'react-router-dom';
import { AppContext } from '../context/AppContext';
import Post from '../components/Post';
import Spinner from '../components/Spinner';
export default function DetailBlog() {
const { loading, setLoading } = useContext(AppContext);
const [mainBlog, setMainBlog] = useState(null);
const [relatedBlogs, setRelatedBlogs] = useState([]);
const location = useLocation();
const blogId = location.pathname.split('/').at(-1);
const newBaseUrl = "https://codehelp-apis.vercel.app/api/get-blog";
async function fetchBlogData() {
setLoading(true);
let url = `${newBaseUrl}?blogId=${blogId}`
try {
const result = await fetch(url);
const data = await result.json();
console.log("api res");
console.log(data);
setMainBlog(data.blog);
setRelatedBlogs(data.relatedBlogs);
console.log(mainBlog);
}
catch (e) {
console.log(e);
}
setLoading(false);
}
useEffect(() => {
if (blogId) {
fetchBlogData();
}
}, [location.pathname]);
return (
<div className="w-full h-full flex flex-col items-center justify-center gap-x-1 relative">
{mainBlog && <Header text={`${blogId} - ${mainBlog.title}`} />}
<div className='max-w-[620px] w-11/12 py-3 flex flex-col gap-y-7 my-[70px]'>
{loading ? (
<Spinner />
) : mainBlog && (
<div>
<Post post={mainBlog} />
<h2 className='py-4 text-3xl font-bold'>Related Blogs</h2>
<div className='flex flex-col gap-y-7'>
{relatedBlogs.map((blog) => (
<Post key={blog.id} post={blog} />
))}
</div>
</div>
)}
</div>
<BackButton />
</div>
)
}
我期待一个空白页面,假设条件渲染仅检查初始状态。
添加条件“mainBlog &&”,表示只有当mainBlog有数据(不为空或未定义)时,“&&”后面的代码才有效。在你的情况下,只有在调用 setState 之后,mainBlog 才有数据