【发布时间】:2021-03-29 23:57:51
【问题描述】:
我正在尝试实现当用户在网站上上传他们的个人资料图片时,它会自动将旧的个人资料图片更改为新的个人资料图片,而不是用户必须注销并重新登录才能使其正常工作。
这是我的前端代码库:
const UserCard = ({ picture, name, userEmail, isVerified, id, setPicture, setUser}) => {
const [imageSelected, setImageSelected] = useState("");
useEffect(() => {
if (imageSelected !== '') {
uploadImage();
}
}, [imageSelected]);
const uploadImage = () => {
const formData = new FormData();
formData.append("file", imageSelected);
formData.append("id", id);
axios
.post("/api/v1/users/upload/image", formData, {
headers: { "Content-Type": "multipart/form-data" },
})
.then((response) => {
setPicture(response.data.data.imageUrl);
setUser(prev => ({ ...prev, picture: response.data.data.imageUrl }));
});
};
// End of Method
const inputFile = useRef(null);
const onButtonClick = () => {
// `current` points to the mounted file input element
inputFile.current.click();
};
return (
<div className="avatar--icon_profile">
<Card className="profile--card_container">
<CardContent>
{picture ? (
<div>
<input
className="my_file"
type="file"
ref={inputFile}
onChange={(e) => setImageSelected(e.target.files[0])}
/>
<div className="profile-image">
<Avatar
src={picture}
alt="Avatar"
className="avatar--profile_image"
onClick={onButtonClick}
/>
</div>
</div>
</div>
这是我的后端路由器,用于将图像从客户端发送到云端(我存储所有图像):
router.post('/upload/image', function (req, res, next) {
const dUri = new Datauri();
const dataUri = (req) => dUri.format(path.extname(req.name).toString(), req.data);
if (req.files !== undefined && req.files !== null) {
const { file, id } = req.files;
const newFile = dataUri(file).content;
cloudinary.uploader.upload(newFile)
.then(result => {
const imageUrl = result.url;
const data = {id : req.body.id, imageUrl };
updateAvatar(data);
return res.status(200).json({ message: 'Success', data: { imageUrl } });
}).catch(err => res.status(400).json({message:'Error', data: { err}}));
} else {
return res.status(400).json({ message: 'Error' });
}
});
我怎样才能实现它?
添加了 GlobalState.js:
const GlobalState = (props) => {
// User State -----------------------------------------------------------------------------
const [currentUser, setUser] = useState(props.serverUserData);
// This method is passed through context to update currentUser
const updateUser = (userData) => {
setUser(userData);
};
// Modal State -----------------------------------------------------------------------------
const [isModalOpen, setModalOpenState] = useState(false);
const [modalToDisplay, setModalToDisplay] = useState("signup");
// This function will be provided to any function that needs to toggle the modal.
const toggleModal = () => {
// Take the previous state and flip it.
setModalOpenState((prevState) => !prevState);
};
// This method is passed through context to update the next modal to open.
const setModal = (name) => {
// Take the passed in modal name and set state.
setModalToDisplay(name);
};
// Loading State ---------------------------------------------------------------------------
// NOT REACT STATE
const [loading, setLoadingState] = useState(false);
// This state will be used as messages in effects to refetch data.
const [reloadThisData, setWhatToReload] = useState("");
// User profile id for query ----------------------------------------------------------------
const [userProfileId, setUserProfileId] = useState("");
// Flag to determine if the header should change css style. ----------------------------------------------------------------
const [adjustBrightness, setAdjustBrightness] = useState(false);
// This is the object passed to GlobalContext.Provider
const providerValues = {
isModalOpen,
toggleModal,
modalToDisplay,
setModal,
currentUser,
updateUser,
loading,
setLoadingState,
reloadThisData,
setWhatToReload,
userProfileId,
setUserProfileId,
adjustBrightness,
setAdjustBrightness,
};
return (
<GlobalContext.Provider value={providerValues}>
{props.children}
</GlobalContext.Provider>
);
};
export default GlobalState;
添加了 console.log(currentUser):
{id: "a9aa869e-e28b-4a06-b5c7-88571d490e04", name: "nhan nguyen", email: "nhannguyen4119@gmail.com", publicId: "nh1615539696370", picture: "http://res.cloudinary.com/teammateme/image/upload/v1617073225/hvckrm6bklbpjk9njrlf.jpg", …}
email: "nhannguyen4119@gmail.com"
id: "a9aa869e-e28b-4a06-b5c7-88571d490e04"
isSessionValid: true
name: "nhan nguyen"
picture: "http://res.cloudinary.com/teammateme/image/upload/v1617073225/hvckrm6bklbpjk9njrlf.jpg"
publicId: "nh1615539696370"
__proto__: Object
编辑后更新我的代码:
const UserProfile = () => {
const appState = useContext(GlobalContext);
const { currentUser, setUser } = appState;
const { email, name, id } = currentUser;
const [isVerified, setIsVerified] = useState(false);
const [picture, setPicture] = useState(currentUser.picture);
const checkVerificationData = () => {
axios.get("/api/v1/profiles/profile").then((res) => {
const { data } = res;
if (data.verifiedDT) {
setIsVerified(data.verifiedDT);
}
});
};
useEffect(() => {
checkVerificationData();
}, [isVerified]);
const classes = useStyles();
return (
<div className={classes.root}>
<Grid item xs={12}
container
direction="row"
justify="center"
alignItems="center"
spacing={4}>
<Grid item>
<Grid item>
<UserCard
picture={picture}
setPicture={setPicture}
userEmail={email}
name={name}
isVerified={isVerified}
id={id}
setUser={setUser}
/>
<br />
</Grid>
<div>
<Grid item>
<div className="profile--layout_userInfo">
<Grid item>
<UserInfo />
</Grid>
</div>
</Grid>
</div>
</Grid>
<div>
<Grid item>
<div className="profile--layout_ratings_reviews_block">
<UserRatingsDetailed userEmail={email} />
</div>
</Grid>
</div>
</Grid>
</div>
);
};
export async function getServerSideProps(context) {
let serverUserData = {};
if (
context.req.session.passport !== undefined &&
context.req.session.passport.user !== undefined
) {
const userPassportInfo = context.req.session.passport.user;
const { id, name, email, publicId, picture } = userPassportInfo;
const isSessionValid = context.req.isAuthenticated();
serverUserData = {
id,
name,
email,
publicId,
picture,
isSessionValid,
};
}
return { props: { serverUserData } };
}
UserProfile.propTypes = {
serverUserData: PropTypes.object,
};
export default UserProfile;
【问题讨论】:
-
您提到注销并登录是显示新个人资料图片的方式,而不是简单的页面刷新。这是因为您在登录过程中进行了头像信息的初始拉取吗?
-
@HenryEcker 我不明白你所说的初始拉动是什么意思?
-
我想我的问题是:您通常如何检索用户的个人资料图片?在
uploadImage函数结束时执行该过程不是一个选项吗? -
我通过上下文检索用户信息。我在帖子中添加了我的上下文
-
那么我的建议是在您的全局上下文管理中添加类似
getUserProfileImage的内容,并在您上传新图像后调用它。或者,由于您似乎正在返回照片的新网址,请添加updateUserProfileLink并将新网址传递给该网址。