TS2559错误求助:React Post组件类型不匹配问题排查
解决TS2559错误:Type '{ children: never[]; }' 与组件props不匹配
错误信息
| undefined; }'. |
|---|
| {posts} |
30 | | ^^^^ 31 | 32 | 33 |
问题代码
Feed组件
import React, { useEffect, useState } from 'react'; import { Outlet } from 'react-router'; import Post from './Post'; import {List} from './List' async function getJSON(url: string) { const res = await fetch(url); return res.json(); } export function Feed() { const [posts, setPosts] = useState([{id: '', title: 'initial state'}]) const [page, setCount] = useState(0); useEffect(() => { async function setData() { setPosts(await getJSON(`./data/posts.json?page=${page}`)); } setData(); }, [page]) useEffect(() => { console.log('render Feed'); console.log(posts) }) return <div style={{backgroundColor:'#FAFAFA'}}> <List> {posts} <Post> </Post> </List> {/* <Post> </Post> */} <p> <button onClick={() => setCount(page + 1)}>Page {page}</button> </p> </div> }
Post组件
import React, { useEffect, useState } from 'react'; import { Link, useParams } from "react-router-dom"; import {List} from './List' async function getJSON(url: string) { const res = await fetch(url); return res.json(); } interface IPost { id: string; title: string; } export default function Post({ post }: { post?: IPost }) { const [numLikes, addLike] = useState(0); const [dynamicPost, setDynamicPost] = useState({ title: '', id: '' }); const params = useParams(); useEffect(() => { async function setDynamicData() { console.log('setDynamicData works') setDynamicPost(await getJSON(`./data/post.${params.postId}.json`)) } if (!post) { setDynamicData(); } console.log('post is set!') }, [params.postId, post]); return <div> {post ? <div> <PostBox> <h2><Link style={{color: 'black', textDecoration: 'none' }} to={`/posts/${post?.id}`}>{post?.title || dynamicPost?.title}</Link></h2> <p>Num likes {numLikes}</p> <Like onLike={() => addLike(numLikes + 1)}> <strong>Bla bla</strong> </Like> </PostBox> </div> : <div><h2 style={{ color: "red" }}>no posts yet</h2></div>} </div> } interface IPropsLike { onLike: () => void; children: JSX.Element; } function Like({ onLike, children }: IPropsLike) { return <button onClick={onLike}>{children}</button> } function PostBox({ children }: { children: JSX.Element[] }) { return <div style={{ border: '4px solid black', color:"black", marginBottom: '1em', width: '100%', textAlign: 'center'}}> {children} </div> }
问题原因及修复方案
核心问题
- Post组件未声明接收children:Post组件的props仅定义了
post?: IPost,但你在Feed中给<Post>标签添加了空的子节点,TypeScript检测到传递了未声明的children属性,触发类型不匹配错误。 - posts数组渲染方式错误:直接在
<List>中写{posts}会把数组对象直接输出为文本,无法渲染对应的Post组件。
修复步骤
1. 移除Post组件的空子节点
将Feed中的:
<Post> </Post>
修改为:
<Post />
2. 正确遍历posts数组渲染Post组件
在Feed组件中遍历posts数组,给每个Post组件传递对应的post数据:
<List> {posts.map(post => ( <Post key={post.id} post={post} /> ))} </List>
这样既解决了类型错误,又能正确渲染所有帖子内容。
3. 可选:支持Post组件接收children(若有需求)
如果需要Post组件支持子节点,可以修改其props定义:
export default function Post({ post, children }: { post?: IPost; children?: React.ReactNode }) { // 原有逻辑保持不变 return <div> {/* 原有渲染内容 */} {children} </div> }
内容的提问来源于stack exchange,提问作者tal moshel
相关产品推荐
相关产品推荐

