React+TypeScript父子组件传Props报错:IProduct类型不匹配IProduct[]
React+TypeScript组件Props类型不匹配问题解决
问题场景
父组件Contents通过Context获取products数组,遍历数组时给子组件Products传递单个产品对象,运行时报错:
Type 'IProduct' is missing the following properties from type 'IProduct[]': length, pop, push, concat, and 29 more
错误原因
- 父组件中,
products.map((prod) => <Products products={prod} />)里的prod是单个IProduct对象,但被传给了子组件的products属性 - 子组件定义的Props类型是
IState,而IState中的products是IProduct[]数组类型,导致单个对象与数组类型不匹配
修复方案
根据组件职责选择以下两种方案之一:
方案1:子组件接收单个产品对象(推荐)
子组件负责渲染单个产品,Props类型改为单个IProduct,父组件遍历传递每个产品:
修改后的子组件代码
import { IProduct } from "../context/Context"; // 定义子组件Props类型:接收单个product对象 const Products: React.FC<{ product: IProduct }> = ({ product }): JSX.Element => { return ( <div className="products_container"> <div className="product-card"> <img src={product.image} alt={product.name} /> <h4>{product.name}</h4> <p>¥{product.price}</p> <span>{product.inStock > 0 ? '有货' : '缺货'}</span> {/* 其他产品属性渲染 */} </div> </div> ); }; export default Products;
修改后的父组件代码
import Products from './Products'; import { CartContext } from "../context/Context"; const Contents: React.FC = () => { const { state: { products } } = useContext(CartContext); return ( <div className="home-content"> {/* 遍历数组,传递单个产品对象,添加key属性 */} {products.map((prod) => ( <Products key={prod.id} product={prod} /> ))} </div> ); }; export default Contents;
方案2:子组件接收整个产品数组
如果子组件负责遍历并渲染所有产品,父组件直接传递整个数组:
修改后的父组件代码
import Products from './Products'; import { CartContext } from "../context/Context"; const Contents: React.FC = () => { const { state: { products } } = useContext(CartContext); return ( <div className="home-content"> {/* 直接传递整个products数组 */} <Products products={products} /> </div> ); }; export default Contents;
修改后的子组件代码
import { IProduct } from "../context/Context"; // 定义子组件Props类型:接收products数组 interface ProductsProps { products: IProduct[]; } const Products: React.FC<ProductsProps> = ({ products }): JSX.Element => { return ( <div className="products_container"> {/* 子组件内部遍历数组渲染 */} {products.map((item) => ( <div key={item.id} className="product-card"> <img src={item.image} alt={item.name} /> <h4>{item.name}</h4> <p>¥{item.price}</p> <span>{item.inStock > 0 ? '有货' : '缺货'}</span> </div> ))} </div> ); }; export default Products;
内容的提问来源于stack exchange,提问作者The Dead Man
相关产品推荐
相关产品推荐

