React,材料UI:
如下面的代码所示,我有一个包含一列TextFields的表。在blur/focusOut事件中,TextFields调用validateItem()方法,该方法发出服务器请求以验证该项。如果验证失败,则UI应弹出一个带有错误消息的对话框。用户在对话框上单击“确定”后**(或单击屏幕上的任何其他位置以关闭对话框,或执行任何其他操作)**,对话框应关闭,并且应清除并聚焦同一TextField,以便用户可以重新输入有效数据。
然而,当用户点击对话框中的确定(或在对话框显示时执行任何其他操作)时,OnBlur和validateItem()会再次被触发,因此对话框会重新打开。如何防止这种行为,并重新聚焦到前面提到的同一个文本字段?
我在想,也许在对话框打开后,用户界面可以以某种方式等待用户的输入,直到框关闭(以防止onBlur触发任何动作),但我不知道如何实现这一点。
export const MyComponent = ({initialPrompts}: any) => {
const [prompts, setPrompts] = useState<ServerData[]>(initialPrompts);
const [errorDialogOpen, setErrorDialogOpen] = useState(false);
const [errorErrorMsg, setErrorErrorMsg] = useState('');
const handleDialogOpen = () => {
setErrorDialogOpen(true);
};
const handleDialogClose = () => {
setErrorDialogOpen(false);
};
async function validateItem(e: any, promptId: number, arrIndex: number) {
const response = await fetch(`http://localhost:5276/Validateitems?promptId=${promptId}&item=${e.target.value}`);
if (!response.ok) {
const text = await response.text();
setErrorErrorMsg(text)
handleDialogOpen();
throw new Error("An item validation error has occurred.");
}
const data = await response.json();
// TODO: make sure data is sucesss
if (response.ok) {
const updatedPrompts = prompts.map(x => x.promptId === promptId ? { ...x, isValidateditem: true} : x );
setPrompts(updatedPrompts);
}
}
return (
<div style={{ width: '700px' }}>
<Dialog open={errorDialogOpen} onClose={handleDialogClose} >
<DialogTitle> {"Error"} </DialogTitle>
<DialogContent>
<DialogContentText> {errorErrorMsg} </DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={handleDialogClose} autoFocus> OK </Button>
</DialogActions>
</Dialog>
<TableContainer component={Paper}>
<Table size="small">
<TableBody>{
prompts.map((item, index) => <TableRow key={'trow'+index}>
<TableCell>{item.prompt}</TableCell>
<TableCell>
<TextField key={'tfield'+index}
variant="outlined"
size="small"
fullWidth
error={item.isValidateditem === false}
inputRef={(input) => index === 0 && input?.focus()}
onBlur={(e) => validateItem(e, item.promptId, index)}
/>
</TableCell>
</TableRow>)
}</TableBody>
</Table>
</TableContainer>
<br/>
<Button variant="contained" size='small'>Done</Button>
<Button variant="contained" size='small' style={{float: 'right'}}>Reset</Button>
</div>
)
}
1条答案
按热度按时间py49o6xq1#
我有一个解决这个错误的办法。
尝试设置另一个状态,例如
preventBlur
,初始值为false。每次打开DialogBox
时,将其设置为true。在validateItem
函数中检查preventBlur
的值,如果为true,则从函数返回,并尝试将其设置为false。我希望这会有所帮助。