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

React Quiz应用点击答案时API重复调用问题求助

解决Quiz应用点击答案时API重复调用的问题

常见问题原因及修复方法

1. 别在组件渲染阶段直接调用API

要是你把API调用直接写在组件函数里(没放在useEffect或者事件回调里),每次组件重新渲染(比如点答案触发state更新)都会重新跑一遍API请求。

错误写法:

function Quiz() {
  // 组件每次渲染都会触发这个API请求
  fetch('/api/quiz')
    .then(res => res.json())
    .then(data => setQuestions(data));

  // 其他代码...
}

改法:把API调用放进useEffect,并且设置正确的依赖项:

import { useEffect, useState } from 'react';

function Quiz() {
  const [questions, setQuestions] = useState([]);

  useEffect(() => {
    // 只在组件第一次挂载时调用一次API
    const getQuestions = async () => {
      const res = await fetch('/api/quiz');
      const data = await res.json();
      setQuestions(data);
    };
    getQuestions();
  }, []); // 空数组依赖,保证只执行一次

  // 其他代码...
}

2. 检查点击事件里的冗余API调用

如果点答案的时候,你的点击回调里又调用了获取题目列表的API,那肯定会触发重复请求。

错误写法:

const handleAnswerClick = (answer) => {
  // 多余操作:这里又调用了获取题目的API
  fetch('/api/quiz')
    .then(res => res.json())
    .then(data => setQuestions(data));
  // 其他处理逻辑...
};

改法:点击事件只处理答案校验、得分更新这类逻辑,别重复调用获取题目的API:

const handleAnswerClick = (answer) => {
  // 只处理答案相关逻辑,比如判断对错、更新得分
  if (answer.isCorrect) {
    setScore(prev => prev + 1);
  }
  // 如果要加载下一题,就调用获取单题的API,别重新拉取全部题目
};

3. 减少不必要的组件重渲染

要是父组件的state更新导致Quiz组件反复渲染,也可能间接触发API重复调用(尤其是useEffect依赖项没设置对的时候)。可以用React.memo包裹组件,减少无意义的重渲染:

const Quiz = React.memo(() => {
  // 组件逻辑...
});

另外检查useEffect的依赖项,确保只有依赖变化时才重新调用API。比如要根据当前题目ID加载下一题,依赖项就设为题目ID:

useEffect(() => {
  const getNextQuestion = async () => {
    const res = await fetch(`/api/quiz/${currentQuestionId}`);
    const data = await res.json();
    setCurrentQuestion(data);
  };
  getNextQuestion();
}, [currentQuestionId]); // 只有currentQuestionId变化时才调用

4. 给API请求加防抖或取消机制

如果某些场景必须调用API,可以用防抖限制请求频率,或者用AbortController取消未完成的重复请求:

useEffect(() => {
  const controller = new AbortController();
  const signal = controller.signal;

  const getQuestions = async () => {
    try {
      const res = await fetch('/api/quiz', { signal });
      const data = await res.json();
      setQuestions(data);
    } catch (err) {
      if (err.name !== 'AbortError') {
        console.error('请求出错:', err);
      }
    }
  };

  getQuestions();

  // 组件卸载或者依赖变化时,取消未完成的请求
  return () => controller.abort();
}, []);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 01:41:18