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

React电影搜索应用API错误输入崩溃及降级UI需求解决

解决React电影搜索应用API错误输入崩溃问题并添加降级UI

直接上修改后的完整代码:

import React, { useState, useEffect } from "react";
import axios from "axios";

export default function App() {
  const [text, setText] = useState("");
  const [movie, setMovie] = useState([]);
  // 新增错误状态,存储API返回的错误信息
  const [error, setError] = useState(null);

  const changeText = (event) => {
    setText(event.target.value);
  };

  useEffect(() => {
    axios
      .get(`http://www.omdbapi.com/?s=king&apikey=4efa7c6`)
      .then((response) => {
        // 先判断Search字段是否存在
        if (response.data.Search) {
          setMovie(response.data.Search);
          setError(null); // 清空错误状态
        } else {
          setMovie([]);
          setError(response.data.Error || "加载失败,请稍后重试");
        }
      })
      .catch(() => {
        // 处理网络请求失败的情况
        setMovie([]);
        setError("网络异常,请检查连接后重试");
      });
  }, []);

  const getMovie = (e) => {
    e.preventDefault();
    if (text.length === 0) {
      alert("Please Enter Movie Name..!");
      return;
    }

    axios
      .get(`http://www.omdbapi.com/?s=${text}&apikey=4efa7c6`)
      .then((response) => {
        if (response.data.Search) {
          setMovie(response.data.Search);
          setError(null);
        } else {
          setMovie([]);
          // 用API返回的错误信息,没有的话用默认提示
          setError(response.data.Error || "未找到相关电影");
        }
      })
      .catch(() => {
        setMovie([]);
        setError("网络异常,请检查连接后重试");
      });
  };

  return (
    <>
      <nav className="navbar navbar-expand-lg bg-dark ">
        <div className="container-fluid">
          <a
            className="navbar-brand"
            href="#"
            style={{ color: "crimson", fontWeight: "bolder" }}
          >
            Mflix
          </a>
          <button
            className="navbar-toggler"
            type="button"
            data-bs-toggle="collapse"
            data-bs-target="#navbarSupportedContent"
            aria-controls="navbarSupportedContent"
            aria-expanded="false"
            aria-label="Toggle navigation"
          >
            <span className="navbar-toggler-icon bg-light"></span>
          </button>
          <div className="collapse navbar-collapse" id="navbarSupportedContent">
            <form className="d-flex" role="search" onSubmit={getMovie}>
              <input
                className="form-control me-3 "
                type="search"
                placeholder="Search"
                aria-label="Search"
                value={text}
                onChange={changeText}
              />
              <button className="btn btn-outline-success " type="submit">
                Search
              </button>
            </form>
          </div>
        </div>
      </nav>

      <div className="container my-3">
        {/* 错误状态显示降级UI */}
        {error && (
          <div className="alert alert-danger text-center" role="alert">
            {error}
          </div>
        )}
        {/* 无错误但无数据时的提示 */}
        {!error && movie.length === 0 && (
          <div className="text-center py-5">
            <h5>请输入电影名称进行搜索</h5>
          </div>
        )}
        {/* 有数据时渲染电影卡片 */}
        {movie.length > 0 && (
          <div className="row ">
            {movie.map((value, index) => {
              return (
                <div className="col-md my-3 " key={index}>
                  <div
                    className="card col-3 mx-auto"
                    style={{ width: "14rem" }}
                    id="res"
                  >
                    <img
                      src={value.Poster}
                      className="card-img-top"
                      alt={value.Title}
                      onError={(e) =>
                        (e.target.src =
                          "https://feb.kuleuven.be/drc/LEER/visiting-scholars-1/image-not-available.jpg/image")
                      }
                    />
                    <div className="card-img-overlay">
                      <h5 className="card-title1" id="type">
                        {value.Year}
                      </h5>
                    </div>
                    <div className="card-body bg-secondary">
                      <p className="card-text" style={{ fontWeight: "bolder" }}>
                        {value.Title}
                      </p>
                    </div>
                  </div>
                </div>
              );
            })}
          </div>
        )}
      </div>
    </>
  );
}

关键改动说明:

  • 新增错误状态error:专门用来存储API返回的错误信息或网络异常提示,方便展示降级UI
  • API请求安全处理:
    • 每次请求后先判断response.data.Search是否存在,避免直接访问undefined导致崩溃
    • 给axios请求添加catch分支,处理网络请求失败的情况
  • 条件渲染逻辑:
    • 有错误时显示红色警告框的降级UI
    • 无错误但无电影数据时,显示友好的提示文字
    • 只有当有电影数据时才渲染卡片列表,彻底避免map调用在undefined上的崩溃问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 15:58:21