我有一个问题,我试图解决一段时间:如何触发此获取:const { data: warrantyInfo } = warrantyApi.useGetWarrantyInfoQuery(materials[0].serialNumber);
只有当我键入的东西在serialNumber
输入使用setTimeout(),1000
?
当前在页面加载和用户在serialNumber
输入中执行的每种类型时触发。
我尝试了一些方法,但不起作用,因为这是一个钩子,我不能将它用于另一个函数或useEffect
。
import { useState } from 'react';
import { toast } from 'react-toastify';
import { styled } from '@mui/material/styles';
import Dialog from '@mui/material/Dialog';
import DialogTitle from '@mui/material/DialogTitle';
import DialogContent from '@mui/material/DialogContent';
import DialogActions from '@mui/material/DialogActions';
import IconButton from '@mui/material/IconButton';
import { isBefore, parseISO } from 'date-fns';
import { ArrowLeft, ArrowRight, ArrowRightLong, CheckOutline, Close, Table, Trash, Upload } from 'assets/icons';
import { Checkbox, FormControlLabel, Grid, InputAdornment, MenuItem, Select, TextField } from '@mui/material';
const ModalAddC = (props) => {
const { open, handleClose } = props;
const { t } = useTranslation();
const [failedSteps] = useState<Array<number>>([]);
const [activeStep, setActiveStep] = useState<number>(0);
const [fiveYearWarranty, setFiveYearWarranty] = useState<boolean>(false);
const [detailedInformation, setDetailedInformation] = useState<string>('' as string);
const [returnReason, setReturnReason] = useState<string>('' as string);
const [materialInputType, setMaterialInputType] = useState<boolean>(true);
const [materials, setMaterials] = useState<Array<{ serialNumber: string; quantity: number; materialDesignation: string }>>([
{ serialNumber: '', quantity: 0, materialDesignation: '' },
]);
const [fileIsUploaded, setFileIsUploaded] = useState<boolean>(false);
const [commissionName, setCommissionName] = useState<string>('' as string);
const [billNumber, setBillNumber] = useState<string>('' as string);
const { data: warrantyInfo } = warrantyApi.useGetWarrantyInfoQuery(materials[0].serialNumber);
const handleNavigation = (step: number) => {
if (step < activeStep) {
setActiveStep(step);
}
};
const handleNext = () => {
let errors = 0;
if(!commissionName.length){
errors = displayError(t('Commission name is required.'));
}
if(!billNumber.length){
errors = displayError(t('Bill number is required.'));
}
if(!detailedInformation.length){
errors = displayError(t('Detailed information is required.'));
}
if(!returnReason.length){
errors = displayError(t('Return reason is required.'));
}
if(errors){
return;
}
setActiveStep((current) => current + 1);
};
const handleSave = () => {
let errors = 0;
materials.forEach((material) => {
if(!material.serialNumber.length){
errors = displayError(t('Serial Number is required.'));
}
if(!material.quantity){
errors = displayError(t('Quantity is required.'));
}
if(!material.materialDesignation.length){
errors = displayError(t('Material Designation is required.'));
}
})
if(errors){
return;
}
handleClose();
};
const handleDecreaseAmount = (index: number) => {
if (materials[index].quantity > 0) {
setMaterials((current) => {
const newMaterials = [...current];
newMaterials[index].quantity = newMaterials[index].quantity - 1;
return newMaterials;
});
}
};
const handleIncreaseAmount = (index: number) => {
setMaterials((current) => {
const newMaterials = [...current];
newMaterials[index].quantity = newMaterials[index].quantity + 1;
return newMaterials;
});
};
const handleQuantityChange = (index: number, newValue: number) => {
setMaterials((current) => {
const newMaterials = [...current];
newMaterials[index].quantity = newValue;
return newMaterials;
});
};
const handleSerialNumberChange = (index: number, newValue: string) => {
setMaterials((current) => {
const newMaterials = [...current];
newMaterials[index].serialNumber = newValue;
return newMaterials;
});
};
const handleMaterialDesignationChange = (index: number, newValue: string) => {
setMaterials((current) => {
const newMaterials = [...current];
newMaterials[index].materialDesignation = newValue;
return newMaterials;
});
};
const handleCreateNewMaterial = () => {
setMaterials((current) => [...current, { serialNumber: '', quantity: 0, materialDesignation: '' }]);
};
const handleDeleteMaterial = (index: number) => {
if (materials.length > 1) {
setMaterials((current) => {
const newMaterials = [...current];
newMaterials.splice(index, 1);
return newMaterials;
});
}
};
const handleSubmitCommission = () => {
const isWarrantyInfoInPast = warrantyInfo
? isBefore(parseISO(warrantyInfo?.end_date), new Date())
: false;
if(isWarrantyInfoInPast) {
toast.error(t('According to our record, the warranty has expired! Feel free to contact us with any questions!'));
}
handleSave();
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const readUploadFile = (e: any) => {
e.preventDefault();
if (e.target.files) {
const reader = new FileReader();
reader.onload = (e) => {
const data = e.target!.result;
const workbook = xlsx.read(data, { type: 'array' });
const sheetName = workbook.SheetNames[0];
const worksheet = workbook.Sheets[sheetName];
const json = xlsx.utils.sheet_to_json(worksheet);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const newArray = json.map((item: any) => ({
serialNumber: item['Material Nummer'],
quantity: item['Anazhl'],
materialDesignation: '',
}));
setMaterials(newArray);
setFileIsUploaded(true);
};
reader.readAsArrayBuffer(e.target.files[0]);
}
};
const openFileInput = () => {
document.getElementById('hiddenFileInput')!.click();
};
return (
<BootstrapDialog onClose={handleClose} aria-labelledby="customized-dialog-title" open={open} className="rp-modal-add-commission">
<BootstrapDialogTitle id="customized-dialog-title" onClose={handleClose}>
<ProgressBar
steps={[t('Commission'), t('Material')]}
failedSteps={failedSteps}
activeStep={activeStep}
setActiveStep={(step) => handleNavigation(step)}
/>
</BootstrapDialogTitle>
<DialogContent dividers>
<div className="slider" style={{ transform: `translateX(calc(-${activeStep * 80}vw + ${activeStep * 6}px))` }}>
<div className="step">
<span className="section-title">{t('Add commission')}</span>
<Grid container spacing={0}>
<Grid item className="custom-grid" xs={6} md={6} lg={6}>
<br></br>
<span className="input-label">{t('Commission name').toString() + '*'}</span>
<TextField
id="outlined-textfield"
label=""
variant="outlined"
className="custom-text-field"
InputLabelProps={{ shrink: false }}
value={commissionName}
onChange={(e) => setCommissionName(e.target.value)}
error={!commissionName.length}
helperText={!commissionName.length && t('Commission name is required.').toString()}
/>
<FormControlLabel
control={
<Checkbox
color="secondary"
checked={fiveYearWarranty}
onChange={() => setFiveYearWarranty(!fiveYearWarranty)}
/>
}
label={`${t('The product has an extended warranty')}(${t('5-years warranty')})`}
/>
<Grid container spacing={0}>
<Grid item className="custom-inside-grid" xs={6} md={6} lg={6}>
<span className="input-label">{t('Serial Number').toString() + (fiveYearWarranty ? '*' : '')}</span>
<TextField
id="outlined-textfield"
label=""
variant="outlined"
className="custom-text-field"
InputLabelProps={{ shrink: false }}
/>
</Grid>
<Grid item className="custom-inside-grid" xs={6} md={6} lg={6}>
<span className="input-label">{t('Bill Number').toString() + '*'}</span>
<TextField
id="outlined-textfield"
label=""
variant="outlined"
className="custom-text-field"
InputLabelProps={{ shrink: false }}
value={billNumber}
onChange={(e) => setBillNumber(e.target.value)}
error={!billNumber.length}
helperText={!billNumber.length && t('Bill number is required.').toString()}
/>
</Grid>
</Grid>
<FormControlLabel control={<Checkbox color="secondary" />} label={t('Replacement of this position is desired')} />
<span className="input-label">{t('Comment').toString()}</span>
<TextField
id="outlined-textfield"
label=""
variant="outlined"
className="custom-text-field"
InputLabelProps={{ shrink: false }}
multiline
rows={2}
/>
</Grid>
<Grid item className="custom-grid" xs={6} md={6} lg={6}>
<br></br>
<span className="input-label">{t('Detailed information').toString() + '*'}</span>
<Select
value={detailedInformation}
label=""
onChange={(e) => setDetailedInformation(e.target.value as string)}
color="secondary"
error={!detailedInformation.length}
displayEmpty>
<MenuItem value="" disabled>
<span className="placeholder">{t('Please select').toString()}</span>
</MenuItem>
<MenuItem value={'1'}>
<span className="menu-option">{t('Too many products')}</span>
</MenuItem>
<MenuItem value={'2'}>
<span className="menu-option">{t('Incorrect order')}</span>
</MenuItem>
<MenuItem value={'3'}>
<span className="menu-option">{t('Customer cancelled order')}</span>
</MenuItem>
<MenuItem value={'4'}>
<span className="menu-option">{t('Inventory cleanup')}</span>
</MenuItem>
<MenuItem value={'5'}>
<span className="menu-option">{t('Delivery time')}</span>
</MenuItem>
<MenuItem value={'6'}>
<span className="menu-option">{t('Delivery time too long')}</span>
</MenuItem>
<MenuItem value={'7'}>
<span className="menu-option">{t('Products too expensive / incorrect price')}</span>
</MenuItem>
</Select>
{!detailedInformation.length && <span className='detailed-information-err-text'>{t('Detailed information is required.')}</span>}
<br></br>
<span className="input-label">{t('Reason of return').toString() + '*'}</span>
<Select
value={returnReason}
label=""
onChange={(e) => setReturnReason(e.target.value as string)}
color="secondary"
error={!returnReason.length}
displayEmpty>
<MenuItem value="" disabled>
<span className="placeholder">{t('Please select').toString()}</span>
</MenuItem>
<MenuItem value={'1'}>
<span className="menu-option">{t('Like new, not needed by customer')}</span>
</MenuItem>
<MenuItem value={'2'}>
<span className="menu-option">{t('Defective')}</span>
</MenuItem>
<MenuItem value={'3'}>
<span className="menu-option">{t('Transport damage')}</span>
</MenuItem>
<MenuItem value={'4'}>
<span className="menu-option">{t('Wrong delivery')}</span>
</MenuItem>
<MenuItem value={'5'}>
<span className="menu-option">{t('Spare parts inventory reconciliation upon consultation')}</span>
</MenuItem>
</Select>
{!returnReason.length && <span className='return-reason-err-text'>{t('Return reason is required.')}</span>}
<br></br>
<span className="input-label">{t('Pictures/files for return').toString()}</span>
<div className="upload-container">
<Upload className="upload-icon" />
<span className="upload-main-text">{t('Drag or select files here')}</span>
<span className="upload-secondary-text">{t('max. 10MB in PDF, JPG, PNG format')}</span>
</div>
</Grid>
</Grid>
</div>
<div className="step">
<span className="section-title">{t('Add Material')}</span>
<Grid container spacing={0}>
<Grid item className="custom-grid" xs={12} md={12} lg={12}>
<Toggle
items={[<>{t('Manual input')}</>, <>{t('Excel upload')}</>]}
setToggle={(e) => {
setMaterialInputType(e);
setMaterials([{ serialNumber: '', quantity: 0, materialDesignation: '' }]);
setFileIsUploaded(false);
}}
value={materialInputType}
/>
</Grid>
</Grid>
{materialInputType ? (
<>
{materials.map((material, index) => (
<Grid key={'materrial-' + index} container spacing={0}>
<Grid item className="custom-grid" xs={4} md={4} lg={4}>
<span className="input-label">{t('Serial Number').toString()}*</span>
<TextField
id="outlined-textfield"
label=""
variant="outlined"
className="custom-text-field"
InputLabelProps={{ shrink: false }}
value={material.serialNumber}
onChange={(e) => handleSerialNumberChange(index, e.target.value)}
error={!material.serialNumber.length}
helperText={!material.serialNumber.length && t('Serial Number is required.').toString()}
/>
</Grid>
<Grid item className="custom-grid" xs={3} md={3} lg={3}>
<span className="input-label">{t('Quantity').toString() + '*'}</span>
<TextField
type="number"
value={material.quantity}
error={!material.quantity}
// onChange={(e) => setPackagestValue(parseInt(e.target.value))}
onChange={(e) => handleQuantityChange(index, parseInt(e.target.value))}
InputProps={{
startAdornment: (
<InputAdornment position="start">
<IconButton onClick={() => handleDecreaseAmount(index)}>
<ArrowLeft />
</IconButton>
</InputAdornment>
),
endAdornment: (
<InputAdornment position="end">
<IconButton onClick={() => handleIncreaseAmount(index)}>
<ArrowRight />
</IconButton>
</InputAdornment>
),
}}
/>
{!material.quantity && <span className='material-qty-err-text'>{t('Quantity is required.')}</span>}
</Grid>
<Grid item className="custom-grid" xs={4} md={4} lg={4}>
<span className="input-label">{t('Material designation').toString()}*</span>
<TextField
id="outlined-textfield"
label=""
variant="outlined"
className="custom-text-field"
InputLabelProps={{ shrink: false }}
value={material.materialDesignation}
onChange={(e) => handleMaterialDesignationChange(index, e.target.value)}
error={!material.materialDesignation.length}
helperText={!material.materialDesignation.length && t('Material Designation is required.').toString()}
/>
</Grid>
<Grid item className="custom-grid justify-center" xs={1} md={1} lg={1}>
<Trash className="cursor-pointer" onClick={() => handleDeleteMaterial(index)} />
</Grid>
</Grid>
))}
<Grid container>
<Grid item xs={12} md={12} lg={12}>
<button className="add-material-button" onClick={() => handleCreateNewMaterial()}>
{t('Add more materials')}
</button>
</Grid>
</Grid>
</>
) : (
<>
{!fileIsUploaded ? (
<>
{materials.map((material, index) => (
<Grid key={'materrial-' + index} container spacing={0}>
<Grid item className="custom-grid" xs={4} md={4} lg={4}>
<span className="input-label">{t('Serial Number').toString()}*</span>
<TextField
id="outlined-textfield"
label=""
variant="outlined"
className="custom-text-field"
InputLabelProps={{ shrink: false }}
value={material.serialNumber}
onChange={(e) => handleSerialNumberChange(index, e.target.value)}
/>
</Grid>
<Grid item className="custom-grid" xs={3} md={3} lg={3}>
<span className="input-label">{t('Quantity').toString() + '*'}</span>
<TextField
type="number"
value={material.quantity}
// onChange={(e) => setPackagestValue(parseInt(e.target.value))}
onChange={(e) => handleQuantityChange(index, parseInt(e.target.value))}
InputProps={{
startAdornment: (
<InputAdornment position="start">
<IconButton onClick={() => handleDecreaseAmount(index)}>
<ArrowLeft />
</IconButton>
</InputAdornment>
),
endAdornment: (
<InputAdornment position="end">
<IconButton onClick={() => handleIncreaseAmount(index)}>
<ArrowRight />
</IconButton>
</InputAdornment>
),
}}
/>
</Grid>
<Grid item className="custom-grid" xs={4} md={4} lg={4}>
<span className="input-label">{t('Material designation').toString()}*</span>
<TextField
id="outlined-textfield"
label=""
variant="outlined"
className="custom-text-field"
InputLabelProps={{ shrink: false }}
value={material.materialDesignation}
onChange={(e) => handleMaterialDesignationChange(index, e.target.value)}
/>
</Grid>
<Grid item className="custom-grid justify-center" xs={1} md={1} lg={1}>
<Trash className="cursor-pointer" onClick={() => handleDeleteMaterial(index)} />
</Grid>
</Grid>
))}
<Grid container>
<Grid item xs={12} md={12} lg={12}>
<button className="add-material-button" onClick={() => handleCreateNewMaterial()}>
{t('Add more materials')}
</button>
<button
className="add-material-button"
onClick={() => {
setFileIsUploaded(false);
setMaterials([{ serialNumber: '', quantity: 0, materialDesignation: '' }]);
}}>
{t('Replace excel file')}
</button>
</Grid>
</Grid>
</>
) : (
<>
<Grid container spacing={0}>
<Grid item className="custom-grid" xs={4} md={4} lg={4}>
<Table />
<br></br>
<span className="excel-upload-description">
{t('Create your Excel table in the form shown here, or simply use our Excel template.')}
</span>
<br></br>
<button className="add-material-button download-excel-template-button">
{t('Download Excel template')}
</button>
</Grid>
<Grid item xs={8} md={8} lg={8}>
<div className="upload-container">
<Upload className="upload-icon" onClick={openFileInput} />
<span className="upload-main-text">{t('Drag or select files here')}</span>
<span className="upload-secondary-text">{t('max. 10MB in xls, csv format')}</span>
</div>
<input
type="file"
id="hiddenFileInput"
style={{ display: 'none' }}
onChange={readUploadFile}
accept=".xls, .csv, .xlsx"
/>
</Grid>
</Grid>
</>
)}
</>
)}
<Grid container spacing={0}>
<Grid item className="custom-grid" xs={12} md={12} lg={12}></Grid>
</Grid>
</div>
</div>
</DialogContent>
<DialogActions>
{activeStep === 0 && (
<>
<button className="next-step-btn-negative" onClick={() => handleNext()}>
{t('Create and add material later')}
</button>
<button className="next-step-btn" onClick={() => handleNext()}>
{t('Next step')}
<ArrowRightLong className="icon" />
</button>
</>
)}
{activeStep === 1 && (
<button className="next-step-btn" onClick={() => handleSubmitCommission()}>
<CheckOutline className="icon-before" />
{t('Create commission')}
</button>
)}
</DialogActions>
</BootstrapDialog>
);
};
export default ModalAddC;
2条答案
按热度按时间rlcwz9us1#
试试这个技巧
b4lqfgs42#
常规的查询钩子旨在每次组件呈现时调用,例如。从状态更新,并将参数传递到底层查询端点。如果你想对查询的触发时间有更多的控制,那么我建议使用惰性查询钩子,并对返回的触发器函数进行反跳。
使用LazyQuery
示例实施方式:
使用
useEffect
钩子调用去抖动的trigger
函数。debounce
函数