React+TypeScript食谱应用:Recipe组件传值类型不匹配报错
解决方案
你的报错核心原因有两个:一是初始状态recipe为null,但Recipe组件要求接收符合Recipe类型的有效值;二是Recipe组件的props定义有误,它应该接收一个包含recipe属性的对象,而非直接接收Recipe类型的值。以下是具体修复步骤:
1. 修正Recipe组件的Props类型
当前Recipe组件直接把参数当作Recipe类型,但实际上你传递的是{ recipe: xxx }这样的props对象,所以需要调整组件的类型定义:
// Recipe卡片组件修改后 import React from 'react' // 导出类型,方便其他组件引用 export type Recipe = { title: string, servings: string, ingredients: string[] instructions: string[] } // 组件接收的是包含recipe属性的props对象 const Recipe = ({ recipe }: { recipe: Recipe }) => { return ( <div className='p-10'> <div> <h1>Recipe Name</h1> {recipe.title} </div> <div> <h1>Instructions</h1> <ul> {/* map循环需添加key属性,符合React规范 */} {recipe.instructions.map((instruction: string) => <li key={instruction}>{instruction}</li>)} </ul> </div> </div> ) } export default Recipe
2. 给搜索组件的useState指定正确类型
初始recipe为null,所以需要给useState指定联合类型null | Recipe,让TypeScript识别状态的可能值:
// 搜索逻辑组件修改后 'use client' import { useState } from "react"; // 导入组件和对应的类型 import Recipe, { Recipe as RecipeType } from './components/Recipe' const Recipes = () => { const [ingredients, setIngredients] = useState('') // 指定状态类型为null | RecipeType,明确状态的可能取值 const [recipe, setRecipe ] = useState<null | RecipeType>(null) const [ingredientList, setIngredientList] = useState('') const [isLoading, setIsLoading] = useState(1) const getRecipe = async function getRecipe(e: React.FormEvent<HTMLFormElement>){ e.preventDefault() setIngredientList(ingredients) setIsLoading(2) const response = await fetch('/api/recipes', { method: 'POST', body: ingredients }) const fetchedRecipe = await response.json() if (fetchedRecipe){ setRecipe(fetchedRecipe) setIngredients('') console.log(fetchedRecipe) } // 请求完成后重置loading状态 setIsLoading(1) } return ( <> <div> <div> <form onSubmit={getRecipe} > <input className=" bg-blue-600 text-black" type='text' placeholder='add your ingredients' value={ingredients} onChange={(e) => {setIngredients(e.target.value)}}/> <button type="submit">get recipes</button> </form> </div> {/* 条件渲染:优先显示加载状态,有有效值时再渲染Recipe组件 */} {isLoading === 2 ? ( <div>加载中...</div> ) : recipe ? ( <Recipe recipe={recipe}/> ) : null} </div> </> ); }; export default Recipes;
关键说明
- 条件渲染:通过
recipe ? <Recipe recipe={recipe}/> : null确保只有当recipe有有效值时才渲染组件,避免传递null给组件触发类型报错。 - 类型安全:给
useState指定联合类型,让TypeScript明确状态的可能取值,消除类型不匹配的警告。 - Props结构修正:组件的props必须是对象结构,和你传递的
{ recipe: recipe }对应,之前直接接收Recipe类型的写法不符合React组件的props传递逻辑。
内容的提问来源于stack exchange,提问作者Rawle Becerril
相关产品推荐
相关产品推荐

