JavaScript函数未按预期顺序执行,使用Promise仍无法生效问题求助
问题根因
你遇到的问题本质是React的状态更新为异步批量执行:调用setRows更新状态后,当前上下文的rows变量依旧是更新前的旧值,状态变更要等到下一次渲染才会生效。你之前写的setTimeout逻辑只是延迟触发addValuesForSubmission,并没有等待状态更新完成再执行提交逻辑,所以依旧会拿到旧的rows值。
解决方案
方案1:不依赖状态更新,直接拼接提交数据(最稳妥)
不需要等待状态更新,直接把新增的行数据和原有rows拼接后提交,逻辑如下:
- 调整
addValuesForSubmission,返回新增的行数据:
const addValuesForSubmission = () => { if (!isNaN(from) && !isNaN(price) && from !== "" && price !== "") { const data = { priceID: rows.length !== 0 ? rows[rows.length - 1].priceID + 1 : 1, agreementID: agreementID, from: from, to: to, price: price, }; setRows((rows) => [...rows, data]); setNumberRecords(numberRecords + 1); setFrom(""); setTo(""); setPrice(""); setID(id + 1); // 返回新增的行数据用于提交 return data; } return null; };
- 修改
valueSubmission,支持接收额外的待提交行:
const valueSubmission = (extraRow = null) => { var result = errorChecking(); if (result.error === true) { setErrorMessage({ error: false, messages: [] }); setSubmitError(true); setErrorMessage(result); } else { inputRef.current.focus(); // 拼接最新的提交数据,不用等待状态更新 const submitRows = extraRow ? [...rows, extraRow] : rows; agreementpricesServices .updateAgreementPrices({ AgreementPrices: submitRows }) .then(() => { setResubmit(!resubmit); setSuccess(true); }) .catch((error) => { setSubmitError(true); setErrorMessage({ error: true, messages: [error.response.error.error], }); setResubmit(!resubmit); }); } };
- 简化提交逻辑,去掉无效的延迟Promise:
const submitValues = (event) => { event.preventDefault(); const newRow = addValuesForSubmission(); valueSubmission(newRow); };
方案2:通过useEffect监听状态更新完成后提交
如果必须等待状态更新完成再执行提交,可以新增提交标记状态,通过useEffect监听触发:
// 新增提交标记状态 const [isSubmitting, setIsSubmitting] = useState(false); // 监听状态变化,rows更新且提交标记为true时执行提交 useEffect(() => { if (isSubmitting) { valueSubmission(); setIsSubmitting(false); } }, [isSubmitting, rows]) // 修改提交逻辑 const submitValues = (event) => { event.preventDefault(); addValuesForSubmission(); setIsSubmitting(true); }
内容的提问来源于stack exchange,提问作者Selim Choueiter
相关产品推荐
相关产品推荐

