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

React中Axios请求每次渲染自动执行,点击触发失效问题解决

问题:React组件渲染时自动发起Axios请求,需改为点击按钮后执行

我有一个使用Axios获取电影数据的基础React程序,期望仅在用户点击底部按钮后才发起Axios请求并展示数据,但目前请求每次组件渲染时都会自动执行。

尝试过多种onClick写法(如{axiosRequest}、{() => axiosRequest}、{() => axiosRequest()}等),也尝试调整.then的位置,都没解决问题。

原代码如下:

import "./styles.css";
import axios from "axios";
import { useState } from "react";

export default function App() {
  const [movie, setMovie] = useState("");
  const [title, setTitle] = useState("");
  const [runTime, setRunTime] = useState("");
  function getMovie(e) {
    setMovie(e.target.value);
  }
  console.log(movie);

  function axiosRequest() {
    return axios.get(
      "https://www.omdbapi.com/?t=" + movie + "&y=&plot=short&apikey=trilogy"
    );
  }

  axiosRequest().then(function (results) {
    var response = results.request.response;
    var responseObj = JSON.parse(response);

    console.log(responseObj);
    setTitle(responseObj.Title);
    setRunTime(responseObj.Runtime);
  });

  return (
    <div>
      <h1 style={{ "text-align": "center" }}>
        [INSERT CATCH NAME FOR MOVIE SEARCH ENGINGE HERE]
      </h1>
      <p>Hello, what movie would you like to know about:</p>
      <input type="text" onChange={getMovie} />
      <br />
      <br />
      <button onClick={axiosRequest}>submit</button>
      <br />
      <br />
      Title: {title}
      <br />
      Runtime: {runTime}
    </div>
  );
}

解决方案

问题根源:你把axiosRequest().then(...)直接写在了组件函数的顶层代码中,每次组件渲染(比如输入框更新state、组件初次挂载)时,这段代码都会自动执行,导致请求被频繁触发。

修复步骤:

  • 将请求+响应处理的逻辑封装到一个函数中,确保只有点击按钮时才调用这个函数。
  • 优化Axios的响应处理:Axios会自动解析JSON响应,无需手动JSON.parse,直接使用response.data即可。

修改后的完整代码:

import "./styles.css";
import axios from "axios";
import { useState } from "react";

export default function App() {
  const [movie, setMovie] = useState("");
  const [title, setTitle] = useState("");
  const [runTime, setRunTime] = useState("");

  function getMovie(e) {
    setMovie(e.target.value);
  }

  // 封装完整的请求+处理逻辑
  async function handleSubmit() {
    try {
      const response = await axios.get(
        `https://www.omdbapi.com/?t=${movie}&y=&plot=short&apikey=trilogy`
      );
      // Axios自动解析JSON,直接用response.data
      const responseObj = response.data;
      console.log(responseObj);
      setTitle(responseObj.Title);
      setRunTime(responseObj.Runtime);
    } catch (error) {
      // 增加错误处理,避免请求失败导致程序崩溃
      console.error("获取电影数据失败:", error);
    }
  }

  return (
    <div>
      <h1 style={{ textAlign: "center" }}>
        [INSERT CATCH NAME FOR MOVIE SEARCH ENGINGE HERE]
      </h1>
      <p>Hello, what movie would you like to know about:</p>
      <input type="text" onChange={getMovie} />
      <br />
      <br />
      {/* 绑定点击事件到处理函数 */}
      <button onClick={handleSubmit}>submit</button>
      <br />
      <br />
      Title: {title}
      <br />
      Runtime: {runTime}
    </div>
  );
}

关键修改说明:

  • 新增handleSubmit函数,把Axios请求和响应处理逻辑全部放在里面,使用async/await让代码更简洁(也可以继续用.then写法)。
  • 按钮的onClick绑定handleSubmit,确保只有点击时才执行请求逻辑。
  • 移除了原来组件顶层的axiosRequest().then(...)代码,避免自动触发请求。
  • 优化了响应处理,直接使用response.data,去掉多余的JSON.parse。
  • 增加了try/catch错误处理,提升程序健壮性。

如果坚持使用.then写法,handleSubmit可以改成这样:

function handleSubmit() {
  axios.get(`https://www.omdbapi.com/?t=${movie}&y=&plot=short&apikey=trilogy`)
    .then(response => {
      const responseObj = response.data;
      console.log(responseObj);
      setTitle(responseObj.Title);
      setRunTime(responseObj.Runtime);
    })
    .catch(error => {
      console.error("获取电影数据失败:", error);
    });
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 05:24:51