useState 挂钩正在破坏 activePost,因为 useEffect 是由 selectedPost 触发的

useState hook is breaking activePost as useEffect is triggered by selectedPost

我的目标是从 Graphcms 中获取 posts 并填充一个数组 - posts,并将其填充到 postlist 中,然后主要组件将根据什么变化用户点击 post 列表中的 post,我可以看到 posts 数组已填充,但是当我点击 post 列表中的 post 时我收到以下错误

Main.js:22 未捕获类型错误:无法读取未定义的属性(读取 'featuredImage') 在我的文件下方

App.js

function App() {

 const [selectedPost,setSelectedPost] = useState(0);
 const [posts, setPosts] = useState([]);


 useEffect(() => {
   const fetchPosts = async () => {
     const { posts } = await request(
       'https://api-ap-southeast-2.graphcms.com/v2/ckxo1np9m5kw601xpccps4lrn/master',
       `
     { 
       posts {
         id
         title
         slug
         excerpt
         featuredImage
         {
           url
        }
       }
     }
   `
     );
     console.log("print posts " , posts)
     setPosts(posts);
   };

   fetchPosts();
 }, []);

  return ( <div className='app'>
    <Header/>
    {
      posts.length>0 && (<>
        <Main posts={posts} selectedPost={selectedPost}/>  
        <PostList posts={posts} setSelectedPost={setSelectedPost} />
        </>
      )
    }

  
  </div>
  )
}

export default App;

和 Main.js 组件

const Main = ({selectedPost,posts}) => {

    const[activePost,setActivePost] =useState(posts[0])
    console.log("activePost ", activePost)

    useEffect(()=>{
      setActivePost(posts[selectedPost])
    },[posts,selectedPost])
  


    return (
        <div className='main'>
            <div className='mainContent'>
                <div className='postHighlight'>
                    <div className='postContainer'>
                    <img 
                    className='selectedPost'
                    src= {activePost.featuredImage.url}
                    alt=''
                    />
                </div>
                </div>
            
            <div className='postDetails' style={{color:'#fff'}}>
                <div className='title'>
                   {activePost.title} </div>
                    <span className='itemNumber'></span>
                    <span className='postExcerpt'>{activePost.excerpt}</span>
                 
                </div>

           <div className='otherDetails'>
           
          </div>
        </div>
        </div>
    )
}

export default Main

然后我们有 postList.js 文件

const PostList = ({posts,setSelectedPost}) => {
    return (
        <div className='postList'>
            {posts.map(post=>(
                    <div onClick={()=>setSelectedPost(post.id)}>
                        <CollectionCard key={post.slug} title={post.title} excerpt={post.excerpt} imageSrc={post.featuredImage.url}/>

                    </div>
             )) })
            
        </div>
    )
}

export default PostList

根据您的应用,您正在使用所选 post 的索引。 错误来自您的 onclick 函数。您将 post.id 传递给 setSelectedPost(),因此您访问的 posts 数组不正确。因此,undefined。 只需在 map 函数上使用当前的 index

<div className='postList'>
  {posts.map((post, index) => (
     <div onClick={() => setSelectedPost(index)} key={post.slug}>
       <CollectionCard
          title={post.title}
          excerpt={post.excerpt}
          imageSrc={post.featuredImage.url}
       />
     </div>
    ))
   }         
</div>