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

