You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 03:39:55