reactjs onRemove上传图像antDesign +从界面删除项目

u4dcyp6a  于 2022-12-26  发布在  React
关注(0)|答案(1)|浏览(448)

我有一个项目,这个项目有几个接口,这些接口中有一个上传图片的接口,问题出在删除图标上,点击后出现了一个模态,但是在模态出现之前元素就被删除了。
我怎样才能解决这个问题呢?
此文件显示包含上载图像的说明列表

import '../../../styles/input/index.scss';
import '../../../styles/dropzone/index.scss';
import { Button, Col, message, Modal, Row, Spin, Upload, UploadFile } from 'antd';
import { FunctionComponent, useCallback, useRef, useState } from 'react';
import { motion, useAnimation } from 'framer-motion';
import { defaultTranstion } from '../../../constants/framer';
import { Controller } from 'react-hook-form';
import FromElemnetWrapper from '../form-element-wrapper';
import { Delete, UploadCloud } from 'react-feather';
import { getBase64 } from '../../../utils/get-base64';
import _ from 'lodash';
import config from '../../../api/nuclearMedicineApi/config';
import { FormattedMessage } from 'react-intl';
import BasicModal from '../modal';
import { UploadOutlined } from '@ant-design/icons';
import axios from 'axios';
import { IFormError } from '../general-form-containner';

interface DropzoneProps {
    name: string;
    control: any;
    rules?: any;
    label: string;
    disabled?: boolean;
    multiple?: boolean;
    accept?: string;
    refType?: number;
    defaultFileList?: any;
    onRemove?: any;
    customRequest?: (option: any) => void;
    onProgress?: any;
}

const Dropzone: FunctionComponent<DropzoneProps> = ({
    name,
    control,
    rules,
    label,
    disabled,
    multiple,
    accept,
    refType,
    defaultFileList,
    onRemove,
    customRequest,
    onProgress
}) => {
    const focusController = useAnimation();
    const errorController = useAnimation();
    const [previewVisible, setpreviewVisible] = useState(false);
    const [previewImage, setpreviewImage] = useState('');
    const handleCancel = () => setpreviewVisible(false);
    const handlePreview = async (file: any) => {
        if (!file.url && !file.preview) {
            file.preview = await getBase64(file.originFileObj);
        }
        setpreviewImage(file?.preview ?? file.url);
        setpreviewVisible(true);
    };

    const [isModalOpen, setIsModalOpen] = useState(false);
    const [errors, setErrors] = useState<IFormError[]>([]);

    const [visibleModal, setVisibleModal] = useState(false);
    const [removePromise, setRemovePromise] = useState();
    const [deleteVisible, setdeleteVisible] = useState<boolean>(false);
    
    const onDeleteHandle = () => {

        setdeleteVisible(false);
    };

    const deletehandleCancel = () => {
        setdeleteVisible(false);
    };
    let resolvePromiseRef =  useRef<((value: boolean) => void) | undefined>();
    // let resolvePromiseRef = useRef<HTMLInputElement | null>(null)

    const handleRemove = useCallback(() =>{
        const promise = new Promise(resolve => {
          resolvePromiseRef.current = resolve
        });
        setVisibleModal(true);
        return promise;
      }, [])

      const handleOkModalRemove = useCallback(() => {
        if (resolvePromiseRef.current) {
          resolvePromiseRef.current(true)
        }
      }, [removePromise]);
      const handleCancelModalRemove = useCallback(() => {
        if (resolvePromiseRef.current) {
          resolvePromiseRef.current(false); 
          setVisibleModal(false)
        }
      }, [removePromise]);

    return (
        <>
            <FromElemnetWrapper
                focusController={focusController}
                errorController={errorController}
                label={label}
                required={rules.required?.value}
            >
                <Controller
                    control={control}
                    name={name}
                    rules={rules}
                    render={({
                        field: { onChange, onBlur, value, name, ref },
                        fieldState: { invalid, error },

                    }) => {

                        if (invalid) {
                            errorController.start({ scale: 80 });
                        } else {
                            errorController.start(
                                { scale: 0 },
                                { ease: defaultTranstion.ease.reverse() },
                            );
                        }
                        return (
                            <div
                                onBlur={() => {
                                    onBlur();
                                    focusController.start({ scale: 0 });
                                }}
                                onFocus={() => {
                                    focusController.start({ scale: 80 });
                                }}
                                className='relative'

                            >
                                <div className='upload-container'>
                                    <form
                                        className='dropzone needsclick'
                                        id='demo-upload'
                                        action='/upload'
                                    >
                                        {/* <> */}
                                        <Upload
                                            action={`${config.baseUrl}api/services/app/Attachment/Upload`}
                                            headers={config.headers}
                                            ref={ref}
                                            multiple={multiple}
                                            disabled={disabled}
                                            data={{ RefType: refType }}
                                            listType='picture'
                                            fileList={value}
                                            id={name}
                                            accept={accept}
                                            onPreview={handlePreview}
                                            onRemove={handleRemove}
                                            iconRender={
                                                () => {
                                                    return <Spin style={{ marginBottom: '12px', paddingBottom: '12px' }}></Spin>
                                                }
                                            }
                                            progress={{
                                                strokeWidth: 3,
                                                strokeColor: {
                                                    "0%": "#f0f",
                                                    "100%": "#ff0"
                                                },
                                                style: { top: 12 }
                                            }}
                                            beforeUpload={
                                                (file) => {
                                                    console.log({ file });
                                                    return true
                                                }
                                            }

                                        // onProgress= {(event: any) => (event.loaded / event.total) * 100}
                                        // onChange={(e) =>
                                        //     onChange(e.fileList)
                                        // }

                                        // onChange={(response) => {
                                        //     console.log('response: ', response);

                                        //     if (response.file.status !== 'uploading') {
                                        //         console.log(response.file, response.fileList);
                                        //     }
                                        //     if (response.file.status === 'done') {
                                        //         message.success(`${response.file.name} 
                                        //                        file uploaded successfully`);
                                        //     } else if (response.file.status === 'error') {
                                        //         message.error(`${response.file.name} 
                                        //                      file upload failed.`);
                                        //     }
                                        //     else if (response.file.status === 'removed') {
                                        //         message.error(`${response.file.name} 
                                        //                      file upload removed.`);
                                        //     }
                                        // }}

                                        >
                                            <div className='upload-button'>
                                                <div className='wrapper'>
                                                    <motion.div
                                                        className='fas fa-angle-double-up'
                                                        whileHover={{
                                                            y: [
                                                                0, -2, 2,
                                                                0,
                                                            ],
                                                            transition: {
                                                                duration: 1.5,
                                                                ease: 'easeInOut',
                                                                yoyo: Infinity,
                                                            },
                                                        }}
                                                    >
                                                        <UploadCloud
                                                            style={{
                                                                margin: '.2rem',
                                                                display:
                                                                    'inline-block',
                                                            }}
                                                            color='white'
                                                            size={20}
                                                        />
                                                        Upload
                                                    </motion.div>
                                                </div>
                                            </div>
                                        </Upload>
                                        {/*
                                        <Modal
                                            title="Are you sure?"
                                            visible={visibleModal}
                                            onOk={handleOkModalRemove}
                                            onCancel={handleCancelModalRemove}
                                        /> */}

                                        <BasicModal
                                            header={
                                                <>
                                                    <FormattedMessage id={'confirmdeletion'} />
                                                </>
                                            }
                                            headerType='error'
                                            content={
                                                <>
                                                    <Row>
                                                        <Col span={8} offset={4}>
                                                            <Button
                                                                type='primary'
                                                                className='savebtn'
                                                                onClick={onDeleteHandle}
                                                                style={{
                                                                    cursor:
                                                                        Object.keys(errors).length !==
                                                                            0
                                                                            ? 'not-allowed'
                                                                            : 'pointer',
                                                                }}
                                                            >
                                                                <FormattedMessage id={'affirmation'} />
                                                            </Button>
                                                        </Col>
                                                        <Col span={8} offset={4}>
                                                            <Button
                                                                type='default'
                                                                className='savebtn'
                                                                onClick={deletehandleCancel}
                                                                style={{
                                                                    cursor:
                                                                        Object.keys(errors).length !==
                                                                            0
                                                                            ? 'not-allowed'
                                                                            : 'pointer',
                                                                }}
                                                            >
                                                                <FormattedMessage id={'cancel'} />
                                                            </Button>
                                                        </Col>
                                                    </Row>
                                                </>
                                            }
                                            isOpen={visibleModal}
                                            footer={false}
                                            width='35vw'
                                        handleCancel={handleCancelModalRemove}
                                        handleOk={handleOkModalRemove}
                                        />

                                        {/* {_.isEmpty(value) && (
                                            <div className='dz-message needsclick'>
                                                <FormattedMessage id='dropfileshere' />
                                            </div>
                                        )} */}
                                        <BasicModal
                                            isOpen={previewVisible}
                                            header={<FormattedMessage id="Preview image" />}
                                            footer={false}
                                            handleCancel={handleCancel}
                                            content={<img
                                                alt='example'
                                                style={{ width: '100%' }}
                                                src={previewImage}
                                            />}
                                        />
                                        {/* </> */}

                                    </form>
                                </div>
                                {invalid && (
                                    <p className='form-element-error'>
                                        {error?.message}
                                    </p>
                                )}
                            </div>
                        );
                    }}
                />
            </FromElemnetWrapper>
        </>
    );
};

export default Dropzone;
vwkv1x7d

vwkv1x7d1#

为什么不起作用?

https://ant.design/components/upload
onRemove -一个回调函数,将在单击删除文件按钮时执行,当返回值为假或承诺解决(假)或拒绝时,将阻止删除事件
必须返回解析为false的承诺或返回false

如何解决?

必须返回一个promise,因此首先,需要一个ref或state来存储该promise的resolve函数,以便可以在模态中调用它

const resolvePromiseRef = useRef<((value: boolean) => void) | undefined>();

然后,需要将resolve函数赋给ref并返回promise
现在onRemove就等你的承诺来解决

const handleRemove = () =>{
  const promise = new Promise(resolve => {
    resolvePromiseRef.current = resolve
  });
  setVisibleModal(true);
  return promise;
}

现在您的函数处理程序

const handleOkModalRemove = useCallback(() => {
  if (resolvePromiseRef.current) {
    resolvePromiseRef.current(true)
  }
}, [removePromise]);
const handleCancelModalRemove = useCallback(() => {
  if (resolvePromiseRef.current) {
    resolvePromiseRef.current(false)
  }
}, [removePromise]);

您也可以使用state,但我推荐使用ref,因为它在组件更改时不会重新呈现组件。

相关问题