我有一个表单。在表单中,我从用户那里得到brandName,supplierName和过期日期。我使用来自mui库的TextField和提交按钮。我想禁用空表单字段上的提交按钮,并在用户填写所有输入时启用它。这里是我声明useStates的代码
const[brandName, setBrandName] = useState("");
const[supplierName, setSupplierName] = useState("");
const[expiryDate, setExpiryDate] = useState(null);
const[brandNameError, setBrandNameError] = useState(false);
const[supplierNameError, setSupplierNameError] = useState(false);
const[expiryDateError, setExpiryDateError] = useState(false);
const[submitButton, setSubmitButton] = useState(true);
这是我用来验证输入的所有函数
// checking brandName Error
const brandNameValidateOnBlur = ()=>{
if(brandName === ""){
setBrandNameError(true);
}
}
// checking supplier name error
const supplierNameValidateOnBlur = ()=>{
if(supplierName === ""){
setSupplierNameError(true);
}
}
// checking expiry date
const expiryDateValidateOnBlur = ()=>{
if(expiryDate === ""){
setExpiryDateError(true);
}
}
// now checking all inputs again if all inputs are good then
// button should be enabled
const checkAllInputs = ()=>{
if(brandName !== "" && supplierName !== "" && expiryDate !== ""){
setSubmitButton(false);
}else{
setSubmitButton(true);
}
}
这是剩下的代码
<TextField fullWidth id="productName" label="Product Name"
value={brandName.toLowerCase()} variant="outlined"
onChange={(data)=>{setBrandName(data.target.value.toUpperCase());checkAllInputs()}}
onBlur={brandNameValidateOnBlur}
onFocus={()=>setBrandNameError(false)}
error={brandNameError}
helperText = {brandNameError ? "Enter Brand Name" : ""}
/>
<TextField id="supplierName"
label="Supplier Name"
value={supplierName.toLowerCase()} variant="outlined"
onBlur={supplierNameValidateOnBlur}
onFocus={()=>setSupplierNameError(false)}
error={supplierNameError}
helperText={supplierNameError ? "Enter Supplier Name " : ""}
onChange={(data)=>{setSupplierName(data.target.value.toUpperCase());checkAllInputs()}} />
<LocalizationProvider dateAdapter={AdapterDayjs}>
<DesktopDatePicker
label="Date Expiry"
inputFormat="MM/DD/YYYY"
value={expiryDate}
onBlur={expiryDateValidateOnBlur}
onFocus={()=>setExpiryDateError(false)}
error={expiryDateError}
helperText={expiryDateError ? "Enter Expiry Date ": ""}
onChange={(selectedDate)=>
{setExpiryDate(selectedDate.format("MM/DD/YYYY"));checkAllInputs()}}
renderInput={(params) => <TextField {...params} />}
/>
</LocalizationProvider>
<Button type='button' variant='contained' id="submitButton" disabled={submitButton}
style={{backgroundColor:'orangered'}} onClick={addData}>Add Data</Button>
现在的问题是,当我输入一个单词时,我的useState更新,但我的checkAllInputs不工作,因为我想这样,如果我输入一个单词,我的checkAllInputs方法在设置状态之前运行,因为我输入第二个条目,然后它像我想这样工作,所以我不知道我做错了什么
我试着用这样的效果钩
useEffect(()=>{
checkAllInputs();
},[brandName, supplierName, expiryDate]);
它的工作很好,因为我接受了,但我读到它应该是一个昂贵的使用效果
我用的另一种方法
const checkAllInputsWithDom = ()=>{
let brandNameEntry = document.getElementById("brandName").value;
let supplierNameEntry = document.getElementById("supplierName").value;
let expiryDateEntry = document.getElementById("expiryDate").value;
if(brandNameEntry !=="" && supplierNameEntry !== "" && expiryDateEntry !== ""){
setSubmitButton(false);
}else{
setSubmitButton(true);
}
}
它是工作的开箱即用,但我的事情在React,这是违反React原则,以直接操纵圆顶元素,我可以这样做与出使用useeffect挂钩一样,只有与我的metohd和一件事,这没有设置expiryDate错误的日期字段
3条答案
按热度按时间jvlzgdj91#
只要你保持输入值在状态中,你就不需要另一个变量来存储按钮状态。你可以在渲染时计算它。(阅读更多关于避免冗余状态的信息。
你可以这样做:
vojdkbi02#
这是link for codesandbox我建议您重构这6个使用状态,其中只有一个useState作为一个对象,其所有值如下所示:
然后使用如下所示的通用
handleInputChange
对其进行更新:为您提供解决方案
你只需要检查所有的值,然后用isDisabled创建一个布尔值,这样当所有的值都为空时,它只会设置为false。
我已经为您创建了一个代码片段,它需要一些改进,但它将服务于您的目的。链接已经在顶部和here以及
dzjeubhm3#
正如Eduardo Motta de Moraes所建议的,我使用此命令在所有输入验证后启用按钮
这解决了我的问题,谢谢爱德华多·莫塔·德·莫赖斯