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

React中useState与useEffect配合API调用异常求助

React中IMDb API调用返回数据undefined的解决方法

问题背景

将训练营的简单HTML页面重构为React项目,使用useState管理状态,useEffect触发IMDb API调用,但异步流程异常,控制台显示返回数据为undefined,尝试过axios及async/await方式仍未解决。需求是通过useEffect调用API,等待数据返回并解析为JSON,再通过setData更新状态以展示数据。

当前代码

const [inputText, setInputText] = useState('');
const [searchTerm, setSearchTerm] = useState('');
const [data, setData] = useState(null);

const handleChange = (event) => {
  setInputText(event.target.value);
};

const handleSubmit = (event) => {
  event.preventDefault();
  setSearchTerm(inputText)
  console.log(inputText)
  setInputText('')
};

useEffect(() => {
  if (searchTerm) {
    console.log('starting fetch with -> ', `https://imdb-api.com/en/API/SearchTitle/k_ix11kdvq/${searchTerm}`)
    fetch(`https://imdb-api.com/en/API/SearchTitle/k_ix11kdvq/${searchTerm}`)
    .then(res => {
        res.json()
        console.log('json data')
      })
    .then(json => {
        setData(json)
        console.log('setting data to this value', json)
      })
    .then(console.log('current data value after setData runs -> ', data))
  }
}, [searchTerm])

控制台输出

inception
App.js:36 starting fetch with ->  https://imdb-api.com/en/API/SearchTitle/k_ix11kdvq/inception
App.js:45 current data value after setData runs ->  null
App.js:40 json data
App.js:44 setting data to this value undefined
index.js:6 data value within body component currently is undefined
installHook.js:1861 data value within body component currently is undefined
index.js:6 data value within body component currently is undefined
installHook.js:1861 data value within body component currently is undefined
App.js:36 starting fetch with ->  https://imdb-api.com/en/API/SearchTitle/k_ix11kdvq/inception
App.js:45 current data value after setData runs ->  undefined
App.js:40 json data
App.js:44 setting data to this value undefined

错误分析与修复方案

核心错误点

  1. 第一个then未返回JSON数据:res.json()是异步操作,必须返回该结果才能传递到下一个then,否则后续then的json参数会是undefined。
  2. 状态更新后立即打印无效:setData是异步操作,状态更新不会立即生效,后续then中打印的data仍是更新前的旧值。

修复后的代码(async/await版本)

const [inputText, setInputText] = useState('');
const [searchTerm, setSearchTerm] = useState('');
const [data, setData] = useState(null);
const [error, setError] = useState(null); // 新增错误状态管理

const handleChange = (event) => {
  setInputText(event.target.value);
};

const handleSubmit = (event) => {
  event.preventDefault();
  setSearchTerm(inputText);
  setInputText('');
};

useEffect(() => {
  if (!searchTerm) return;

  const fetchMovieData = async () => {
    try {
      console.log('starting fetch with -> ', `https://imdb-api.com/en/API/SearchTitle/k_ix11kdvq/${searchTerm}`);
      const res = await fetch(`https://imdb-api.com/en/API/SearchTitle/k_ix11kdvq/${searchTerm}`);
      // 检查HTTP响应状态,处理请求失败情况
      if (!res.ok) throw new Error(`请求失败,状态码:${res.status}`);
      const jsonData = await res.json();
      setData(jsonData);
      console.log('成功获取数据:', jsonData);
      setError(null); // 清除之前的错误
    } catch (err) {
      setError(err.message);
      console.error('请求出错:', err);
    }
  };

  fetchMovieData();
}, [searchTerm]);

// 组件渲染部分示例
return (
  <div>
    <form onSubmit={handleSubmit}>
      <input 
        value={inputText} 
        onChange={handleChange} 
        placeholder="输入电影名搜索..."
      />
      <button type="submit">搜索</button>
    </form>
    {/* 错误提示 */}
    {error && <p style={{color: 'red'}}>错误:{error}</p>}
    {/* 数据展示 */}
    {data && data.results && (
      <div className="search-results">
        <h3>搜索结果</h3>
        {data.results.map(movie => (
          <div key={movie.id} className="movie-item">
            <h4>{movie.title}</h4>
            <p>{movie.description}</p>
            <img src={movie.image} alt={movie.title} width="100" />
          </div>
        ))}
      </div>
    )}
  </div>
);

关键修复说明

  • 用async/await简化异步流程,代码逻辑更直观。
  • 添加HTTP响应状态检查,捕获请求失败的情况(如API密钥失效、网络异常)。
  • 新增error状态管理错误信息,避免用户看到空白页面。
  • 状态更新后通过组件渲染展示数据,而非立即打印(setData异步特性导致即时打印无意义)。

额外注意事项

  • API密钥安全:不要在前端代码中直接暴露API密钥,建议通过后端代理转发请求,防止密钥被盗用。
  • 防抖优化:频繁输入搜索词会触发多次API调用,可添加防抖函数(如setTimeout延迟执行)减少请求次数。
  • 空值判断:渲染数据前先检查data和data.results是否存在,避免undefined报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 07:15:31