无法使用FormData上传图片

问题描述 投票:0回答:0

我尝试使用 FormData 通过邮寄请求上传图片,但无法正常工作。 Here is the issue

这是我在 Profile.jsx 中的代码,基本上是一个从目录中选择图像的函数,然后将文件发送到 updateCurrentUserAvatar 并在单击按钮提交时发布文件

import React, { useState, useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { getCurrentUserAvatar, setImage, updateCurrentUserAvatar } from '~/features/superAdminSlice';
import Spinner from '~/layouts/components/Spinner';

const SuperAdminAccountProfile = () => {
    const dispatch = useDispatch();
    const userAvatar = useSelector((state) => state.superadmin.avatar);
    const [imageProfile, setImageProfile] = useState(userAvatar);
    const [loading, setLoading] = useState(true);

    useEffect(() => {
        dispatch(getCurrentUserAvatar());
        setImageProfile(userAvatar);
        setLoading(false);
    }, [dispatch, userAvatar]);

    const handleButtonClick = () => {
        const input = document.createElement('input');
        input.type = 'file';
        input.accept = 'image/*';
        input.style.opacity = 0;
        input.style.height = 0;
        input.onchange = (event) => {
            const file = event.target.files[0];
            const reader = new FileReader();
            reader.onload = () => {
                setImageProfile(reader.result);
            };
            reader.readAsDataURL(file);
            setImage(file);
        };
        document.body.appendChild(input);
        input.click();
        document.body.removeChild(input);
    };

    const handleSubmit = (event) => {
        event.preventDefault();
        if (imageProfile) {
            dispatch(updateCurrentUserAvatar(imageProfile));
        }
    };
    return (
        <div style={{ position: 'relative', width: '200px', height: '200px' }}>
            {loading ? (
                <Spinner />
            ) : (
                <>
                    <img src={imageProfile} alt="" style={{ width: '100%', height: '100%' }} />
                    <button
                        type="button"
                        style={{
                            position: 'absolute',
                            top: '50%',
                            left: '50%',
                            transform: 'translate(-50%, -50%)',
                            visibility: 'visible',
                        }}
                        onClick={handleButtonClick}
                    >
                        Change Image
                    </button>
                </>
            )}
            <button type="submit" onClick={handleSubmit}>
                Submit            </button>
        </div>
    );
};

export default SuperAdminAccountProfile;

这是我的带有 updateCurrentUserAvatar 的 Slice.js。

import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import axios from '~/api/axios';
import { getAdmins, register, updateStatus } from '~/services/superAdminService';

const initialState = {
    data: [],
    admins: [],
    isLocked: false,
    currentPage: 1,
    pageSize: 5,
    search: '',
    adminId: '',
    count: '',
    avatar: null,
};

export const getAdminData = createAsyncThunk('superadmin/adminList', async ({ currentPage, pageSize, search }) => {
    try {
        const response = await getAdmins(currentPage, pageSize, search);
        return response;
    } catch (error) {
        console.log(error);
    }
});

export const updateAdminStatus = createAsyncThunk('superadmin/updateData', async (adminId) => {
    try {
        const response = await updateStatus(adminId);
        return response;
    } catch (error) {
        console.log(error);
    }
});

export const createAdmin = createAsyncThunk('superadmin/createAdmin', async (payload) => {
    try {
        const response = await register({
            email: payload.email,
            fullname: payload.fullname,
            username: payload.username,
            password: payload.password,
            confirmPassword: payload.confirmPassword,
        });
        return response;
    } catch (error) {
        console.log(error);
    }
});

export const getCurrentUserAvatar = createAsyncThunk('superadmin/getAvatar', async () => {
    try {
        const response = await axios.get('User/avatar');
        return response.url;
    } catch (error) {
        console.log(error);
    }
});

export const updateCurrentUserAvatar = createAsyncThunk('superadmin/updateAvatar', async (avatar) => {
    try {
        const formData = new FormData();
        formData.append('avatar', avatar);
        const response = await axios.post('User/avatar', formData, {
            headers: { 'Content-type': 'multipart/form-data' },
        });
        console.log(response);
        return response;
    } catch (error) {
        console.log(error);
    }
});

export const superAdminSlice = createSlice({
    name: 'superadmin',
    initialState,
    reducers: {
        setPage: (state, action) => {
            state.currentPage = action.payload;
        },
        setSearch: (state, action) => {
            state.search = action.payload;
            state.currentPage = 1;
        },
        setLock: (state, action) => {
            state.isLocked = action.payload;
        },
        setImage: (state, action) => {
            console.log(action);
            state.avatar = action.payload;
        },
    },
    extraReducers: (builder) => {
        builder
            .addCase(getAdminData.fulfilled, (state, action) => {
                state.data = action.payload.data;
                state.count = action.payload.count;
            })
            .addCase(updateAdminStatus.fulfilled, (state, action) => {
                state.adminId = action.payload.adminId;
                state.isLocked = action.payload.isLocked;
            })
            .addCase(createAdmin.fulfilled, (state, action) => {
                state.admins.push(action.payload);
            })
            .addCase(getCurrentUserAvatar.fulfilled, (state, action) => {
                state.avatar = action.payload;
            })
            .addCase(updateCurrentUserAvatar.fulfilled, (state, action) => {
                state.avatar = action.payload;
            });
    },
});

export const { setPage, setSearch, setLock, setImage } = superAdminSlice.actions;

export default superAdminSlice.reducer;

reactjs file-upload redux-toolkit form-data
© www.soinside.com 2019 - 2024. All rights reserved.