我有一个问题正在努力解决一段时间: 我如何才能触发这个FETCH: const { data: warrantyInfo } = warrantyApi.useGetWarrantyInfoQuery(materials[0].serialNumber);只有当我使用setTimeout(), const { data: warrantyInfo } = warrantyApi.useGetWarrantyInfoQuery(materials[0].serialNumber);0在序列编号输入上输入一些东西时?

当前在页面加载时触发,并在用户在acealNumber输入中执行的每种类型上触发.

我try 了一些方法,但不起作用,因为这是一个钩子,例如,我不能将其用于另一个函数或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;

推荐答案

Try this technique.

import { useEffect, useState } from 'react';

function YourComponent() {
  const [serialNumber, setSerialNumber] = useState('');
  const [debouncedSerialNumber, setDebouncedSerialNumber] = useState('');
  const { data: warrantyInfo } = warrantyApi.useGetWarrantyInfoQuery(debouncedSerialNumber);

  // Update debouncedSerialNumber after a delay
  useEffect(() => {
    const timeoutId = setTimeout(() => {
      setDebouncedSerialNumber(serialNumber);
    }, 1000);

    // Clear the previous timeout when the user types more
    return () => {
      clearTimeout(timeoutId);
    };
  }, [serialNumber]);

  // Handle input change
  const handleInputChange = (e) => {
    setSerialNumber(e.target.value);
  };

  return (
    <div>
      <input
        type="text"
        value={serialNumber}
        onChange={handleInputChange}
        placeholder="Serial Number"
      />
      {/* Render your warrantyInfo data here */}
    </div>
  );
}

Reactjs相关问答推荐

迁移到React Router Dom v6后,我是否错误地使用了Link组件?

props 可以在Reaction中锻造吗?

下拉Tailwind CSS菜单与怪异beviour

使用筛选器的Primereact DataTable服务器端分页?

在React Create App TS项目中安装material UI

对搜索引擎优化来说,react 头盔的异步足够了吗?

如何在REACTIVE js中动态添加或删除输入字段?

更改点几何体的坐标会将其隐藏

列表中的每个子项都应该有一个唯一的keyprops .在react 应用程序中

提前输入错误:选项类型上不存在属性名称

React Js和Firestore中如何将当前ID与集合中的ID查询以仅显示具有相似字段和值的文档-第二部分

React - 函数组件 - 点击两次问题处理

如何在 React.js 中提取 PDF 的内容?

将 clerk 与 supabase 集成的最佳实践

一周前刚开始学习React,一直在调试为什么输入框在每次输入后都没有焦点

如何在 React 中使用 debounce hooks

使用输入类型文本对 useState 和日期做出react

您无权使用阻止 webRequest 侦听器.请务必在 list 中声明 webRequestBlocking 权限

gtag:为什么谷歌分析即使没有被授权也会收集数据

如何在 React x 中返回组件?