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

React.js中数据库total字段与计算值相等时启用禁用按钮

解决方案:React中根据发票数据状态启用提交按钮

原代码存在的问题

  • 错误地在input的Value属性中执行状态更新逻辑,会引发无限重渲染循环(setState触发组件重渲染,重渲染又再次调用setState)
  • 滥用input组件承载业务判断逻辑,input的职责是展示/收集用户输入,不应用来处理数据校验
  • 判断逻辑不合理:使用map遍历每一项,无法高效判断是否存在符合条件的发票项

正确实现方式

方式一:获取数据后直接判断

在接口请求成功后,直接检查返回的数据中是否存在total等于totalVal的项,然后更新按钮状态:

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

const YourComponent = () => {
  const [invoiceData, setInvoiceData] = useState([]);
  const [isSubmitButtonDisabled, setIsSubmitButtonDisabled] = useState(true);
  const totalVal = 20000; // 预设值

  // 获取发票数据并判断状态
  const getInvoiceData = () => {
    axios.get("http://localhost:4000/api/cash/showInvoices")
      .then((res) => {
        const getData = res.data.data;
        setInvoiceData(getData);
        // 判断是否存在total等于totalVal的项
        const hasMatchingTotal = getData.some(item => item.total === totalVal);
        setIsSubmitButtonDisabled(!hasMatchingTotal);
      })
      .catch(err => {
        console.error('获取发票数据失败:', err);
        // 请求失败时保持按钮禁用
        setIsSubmitButtonDisabled(true);
      });
  };

  // 组件挂载时调用接口(可根据需求调整触发时机)
  useEffect(() => {
    getInvoiceData();
  }, []);

  return (
    <div>
      {/* 按需展示发票数据 */}
      {invoiceData.map(item => (
        <div key={item.id}>
          发票总额: {item.total}
        </div>
      ))}
      
      <button
        type="submit"
        disabled={isSubmitButtonDisabled}
        className="btn btn-primary btn-lg"
      >
        Process Data
      </button>
    </div>
  );
};

export default YourComponent;

方式二:使用useEffect监听发票数据变化

如果发票数据可能在其他地方被更新(比如用户操作修改数据),可以用useEffect监听invoiceData的变化,自动更新按钮状态:

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

const YourComponent = () => {
  const [invoiceData, setInvoiceData] = useState([]);
  const [isSubmitButtonDisabled, setIsSubmitButtonDisabled] = useState(true);
  const totalVal = 20000;

  const getInvoiceData = () => {
    axios.get("http://localhost:4000/api/cash/showInvoices")
      .then((res) => {
        setInvoiceData(res.data.data);
      })
      .catch(err => {
        console.error('获取发票数据失败:', err);
        setInvoiceData([]);
      });
  };

  useEffect(() => {
    getInvoiceData();
  }, []);

  // 监听invoiceData变化,自动更新按钮状态
  useEffect(() => {
    const hasMatchingTotal = invoiceData.some(item => item.total === totalVal);
    setIsSubmitButtonDisabled(!hasMatchingTotal);
  }, [invoiceData, totalVal]);

  return (
    <div>
      {invoiceData.map(item => (
        <div key={item.id}>
          发票总额: {item.total}
        </div>
      ))}
      
      <button
        type="submit"
        disabled={isSubmitButtonDisabled}
        className="btn btn-primary btn-lg"
      >
        Process Data
      </button>
    </div>
  );
};

export default YourComponent;

关键说明

  • 使用Array.some()方法高效判断数组中是否存在符合条件的元素,该方法找到第一个匹配项后就会停止遍历,性能优于map
  • 把状态更新逻辑放在接口回调或useEffect中,避免在渲染阶段执行状态更新,防止无限重渲染
  • 移除了无意义的input组件,回归组件的职责单一性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 17:57:51