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

React调用TheCocktailDB接口时drinkList.drinks未定义报错如何解决

问题根因

你出现报错的核心原因是同一个state变量被混用承担了两个完全不同的功能:drinkName既要存用户输入的搜索关键词字符串,又要存接口返回的对象类型的饮品数据,导致中间态触发错误:

  • 用户在输入框输入内容时,drinkName会被赋值为字符串类型的搜索词,此时传给Drinks组件的drinkList是字符串,你的非空判断if (!drinkList)会被跳过(非空字符串判断为真),后续尝试读取字符串的.drinks属性自然会返回undefined。
  • 就算请求成功后把接口返回对象赋值给drinkName,也会覆盖掉用户输入的搜索词,后续二次搜索也会出现逻辑问题。

修复步骤

1. 拆分独立State

在Home.js中拆分两个用途完全独立的state:

import React, { useState } from "react";
import axios from "axios";
import Drinks from "../components/Drinks";

function Home() {
  // 存用户输入的搜索关键词
  const [searchKey, setSearchKey] = useState('');
  // 存接口返回的饮品列表数据
  const [drinkList, setDrinkList] = useState(null);

2. 修正对应业务逻辑

修改事件、请求、传参的逻辑,匹配拆分后的state:

const drinksURL = `https://www.thecocktaildb.com/api/json/v1/1/search.php?s=${searchKey}`;

  function handleChangeDrink(e) {
    setSearchKey(e.target.value);
  }

  const getDrink = () => {
    axios
      .get(drinksURL)
      .then(function (response) {
        setDrinkList(response.data);
      })
      .catch(function (error) {
        console.warn(error);
      });
  };

  return (
    <main className="App">
      <section className="drinks-section">
        <input
          type="text"
          placeholder="Name of drink (e.g. margarita)"
          onChange={handleChangeDrink}
        />
        <button onClick={getDrink}>Get a Drink Recipe</button>
        <Drinks drinkList={drinkList} />
      </section>
    </main>
  );
}

export default Home;

3. 给Drinks组件加严谨的非空判断

兼容搜索无结果、返回数据为空的场景:

import React from "react";

function Drinks({ drinkList }) {
  // 多层判断:数据存在、drinks属性存在、数组长度大于0才渲染内容
  if (!drinkList?.drinks?.length) return <></>;
  return (
    <section className="drinkCard">
      <h1>{drinkList.drinks[0].strDrink}</h1>
    </section>
  );
}

export default Drinks;

内容的提问来源于stack exchange,提问作者mw3981

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 18:45:05