有人能解释一下为什么条件渲染修复了reactjs中setState的异步问题吗?

问题描述 投票:0回答:1

所以我正在制作一个小博客文章项目,在这个项目中我调用了状态“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>
    )
}

我期待一个空白页面,假设条件渲染仅检查初始状态。

javascript reactjs asynchronous react-hooks setstate
1个回答
0
投票

添加条件“mainBlog &&”,表示只有当mainBlog有数据(不为空或未定义)时,“&&”后面的代码才有效。在你的情况下,只有在调用 setState 之后,mainBlog 才有数据

© www.soinside.com 2019 - 2024. All rights reserved.