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
相关产品推荐
相关产品推荐

