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

React中如何延迟重复触发的服务端请求?

待办复选框频繁触发重复请求的防抖方案

你需要的延迟发请求效果用防抖(debounce)逻辑实现即可:用户停止操作300ms后才真正发起请求,操作过程中反复勾选/取消只会重置等待计时,不会发送无效请求。

注意:你原有代码里的setTodos([response.data])存在逻辑问题,会把整个待办列表覆盖成单条数据,下面的修复代码会一并修正这个问题。

核心实现逻辑

  • 用useRef存储不同待办项对应的定时器ID,避免组件重渲染时丢失定时器引用
  • 每次复选框状态变更时,先清除当前待办项之前挂起的未发送请求定时器
  • 重新启动300ms倒计时,倒计时结束后再向服务端发送更新请求
  • 接口返回后匹配待办ID,只更新对应项的完成状态,保留列表其余数据
  • 可选优化:组件卸载时清除所有未执行的定时器,避免内存泄漏

完整修改后代码

import React, { useState, useRef, useEffect } from 'react';
import axios from 'axios';

const Form = () => {
  const [todos, setTodos] = useState([]);
  // 存储每个todo对应的定时器
  const timerRef = useRef({});

  // 组件卸载时清除所有未执行的定时器
  useEffect(() => {
    return () => {
      Object.values(timerRef.current).forEach(timer => clearTimeout(timer));
    }
  }, []);

  const completedOnChangeHandler = (e, id) => {
    const checked = e.target.checked;
    
    // 清除当前todo之前未发送的请求定时器
    if (timerRef.current[id]) {
      clearTimeout(timerRef.current[id]);
    }

    // 设置新的300ms延迟请求
    timerRef.current[id] = setTimeout(() => {
      axios
        .patch(`http://127.0.0.1:8000/todo/todos/${id}/`, {
          completed: checked,
        })
        .then(
          (response) => {
            console.log(response.data);
            // 修正原有状态更新逻辑:只替换对应id的todo项
            setTodos(prev => prev.map(todo => 
              todo.id === id ? response.data : todo
            ));
          },
          (error) => {
            console.log(error);
          }
        );
    }, 300);
  };

  return (
    <form>
          {todos.map((todo) => (
            <ul key={todo.id}>
              <li>{todo.title}</li>
              <li>{todo.description}</li>
              <button>delete</button>
              <input
                type="checkbox"
                placeholder="completed"
                onChange={(e) => completedOnChangeHandler(e, todo.id)}
                checked={todo.completed}
              />
            </ul>
          ))}
    </form>
  );
};

export default Form;

效果说明

  • 用户快速反复勾选/取消同一个复选框时,只有最后一次操作结束后等待300ms才会发送请求,中间的操作都不会触发接口调用
  • 不同待办项的定时器互相独立,操作A待办的复选框不会影响B待办的待发请求
  • 修复了原代码状态更新会覆盖整个列表的bug,列表渲染逻辑正常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 23:42:28