reactjs - 如何在不刷新的情况下上传新图像后更新旧头像图像
问题描述
我不知道我是否需要为此使用像 useContext 这样的全局状态(我在这个项目中没有使用 redux)但我想要做的是,一旦我上传了新图像,它就会从服务器发送回图像数据我设置了那个状态。然后我想用新上传的图像替换屏幕上的现有图像。
所以,这是我的文件输入组件:
import React, { useState } from "react";
import ProgressBar from "../../../shared/components/progressBar/ProgressBar";
const UploadForm = () => {
const [file, setFile] = useState(null);
const [error, setError] = useState(null);
const types = ["image/png", "image/jpg", "image/jpeg"];
const changeHandler = (e) => {
let selected = e.target.files[0];
if (selected && types.includes(selected.type)) {
setFile(selected);
setError("");
} else {
setFile(null);
setError("Please select an image file(png or jpg");
}
};
return (
<form>
<input type="file" onChange={changeHandler} name="image"></input>
<div className="output">
{error && <div className="error">{error}</div>}
{file && <div>{file.name}</div>}
{file && <ProgressBar file={file} setFile={setFile} />}
</div>
</form>
);
};
export default UploadForm;
我的进度条组件:
import React, { useEffect } from "react";
import useStorage from "../../hooks/use-storage";
import { motion } from "framer-motion";
import "./ProgressBar.css";
const ProgressBar = ({ file, setFile }) => {
const { url, progress } = useStorage(file);
useEffect(() => {
if (url) {
setFile(null);
}
}, [url, setFile]);
return (
<motion.div
className="upload-progress"
initial={{ width: 0 }}
animate={{ width: progress + "%" }}
></motion.div>
);
};
export default ProgressBar;
而且,我的上传自定义挂钩。你可以在这里看到我在这里设置图像 url 的状态,但我不知道上传完成后如何更新我的头像组件。
import React, { useState, useEffect, useContext } from "react";
import Axios from "axios";
import { AuthContext } from "../context/auth-context";
const useStorage = (file) => {
const auth = useContext(AuthContext);
const [progress, setProgress] = useState(0);
const [error, setError] = useState(null);
const [url, setUrl] = useState(null);
useEffect(() => {
const formData = new FormData();
formData.append("image", file);
try {
const sendImage = async () => {
const response = await Axios.post(
"http://localhost:8000/api/v1/users/update-avatar",
formData,
{
headers: {
"Content-type": "multipart/form-data",
Authorization: "Bearer " + auth.token,
},
onUploadProgress: (progressEvent) => {
setProgress(
parseInt(
Math.round((progressEvent.loaded * 100) / progressEvent.total)
)
);
},
}
);
// get the new file name from the server so you can show it right away after upload
const { filename, path } = response.data.file;
setUrl({ filename, path });
};
sendImage();
} catch (err) {
setError(err);
console.log(err.response);
}
}, [file]);
return { progress, url, error };
};
export default useStorage;
头像组件
import React, { useContext, useEffect, useState } from "react";
import Axios from "axios";
import { AuthContext } from "../../../shared/context/auth-context";
const Avatar = () => {
const auth = useContext(AuthContext);
const [avatar, setAvatar] = useState(null);
useEffect(() => {
const getAvatarImage = async () => {
const response = await Axios.get(
"http://localhost:8000/api/v1/users/get-avatar",
{ headers: { Authorization: "Bearer " + auth.token } }
);
setAvatar(response.data.avatar);
};
if (auth.token) getAvatarImage();
}, [auth.token]);
return (
<div>
{avatar && (
<img
src={`http://localhost:8000/uploads/images/${avatar}`}
width="200"
alt="avatar image"
/>
)}
</div>
);
};
export default Avatar;
授权上下文
import { createContext } from "react";
export const AuthContext = createContext({
isLoggedIn: false,
userId: null,
token: null,
email: null,
firstName: null,
login: () => {},
logout: () => {},
});
解决方案
推荐阅读
- laravel - Laravel:我如何修复这个特征(带有属性)在创建模型时也可以工作?
- css - 语义 UI,grid class="ui grid celled padded" 的列的 div 子项将不会滚动 - [更新]
- arrays - 如何解决此“未处理的拒绝类型错误:res.xls 不是函数”
- swift - Swift 播放声音适用于模拟器,但不适用于 iPhone
- spring - 如何将spring bean注入(custructor)到Mapstruct的抽象映射器中?
- android - 使用在 react-native-firebase 中设置新的 firebase 应用程序无法从 https://settings.crashlytics.com/spi/v2/platforms/android/apps/ 检索设置
- internet-explorer - 在 Internet Explorer 中制作隐形“占位符”很热门?
- reactjs - 你如何用 Jest 在另一个函数中模拟一个函数
- data-analysis - 有没有办法将 Microsoft Teams 对话历史记录下载到文本文件或 Excel 中?
- sql - 所需格式的 Sql 查询输出