"错误"
验证错误:finishTestRun(C:\Users\daryl\Documents\Full_stack_code\practical_06_solution\learning-app\server\node_modules\yup\lib\util\runTests。js:六十三:20)在C:\Users\daryl\Documents\Full_stack_code\practical_06_solution\learning-app\server\node_modules\yup\lib\util\runTests。js:十七:5 at finishTestRun(C:\Users\daryl\Documents\Full_stack_code\practical_06_solution\learning-app\server\node_modules\yup\lib\util\runTests。js:六十三:11)在C:\Users\daryl\Documents\Full_stack_code\practical_06_solution\learning-app\server\node_modules\yup\lib\util\createValidation。js:七十二:第104话过程processTicksAndRejections(节点:internal/process/task_queues:九十五:5){value:{},path:undefined,type:未定义,错误:['姓名是必填字段','电子邮件是必填字段'],params:undefined,inner:[ValidationError:name是createError(C:\Users\daryl\Documents\Full_stack_code\practical_06_solution\learning-app\server\node_modules\yup\lib\util\createValidation. js:54:21)at C:\Users\daryl\Documents\Full_stack_code\practical_06_solution\learning-app\server\node_modules\yup\lib\util\createValidation. js:72:107 at process. processTicksAndRejections(node:internal/process/task_queues:95:5){value:未定义,路径:'name',类型:'required',错误:[Array],params:【对象】,内部:[]},ValidationError:email是createError(C:\Users\daryl\Documents\Full_stack_code\practical_06_solution\learning-app\server\node_modules\yup\lib\util\createValidation. js:54:21)at C:\Users\daryl\Documents\Full_stack_code\practical_06_solution\learning-app\server\node_modules\yup\lib\util\createValidation. js:72:107 at process. processTicksAndRejections(node:internal/process/task_queues:95:5){value:未定义,路径:'电子邮件',键入:'required',错误:[Array],params:【对象】,内部:[[]}
import React, { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import {
Box,
Typography,
TextField,
Button,
Grid,
List,
ListItem,
ListItemText,
ListItemIcon,
Divider,
} from '@mui/material';
import http from '../http';
import PropTypes from 'prop-types';
import { ToastContainer, toast } from 'react-toastify';
import { useFormik } from 'formik';
import * as yup from 'yup';
import PermIdentityIcon from '@mui/icons-material/PermIdentity';
function Profiles() {
const navigate = useNavigate();
const [user, setUser] = useState(null);
const [selectedImage, setSelectedImage] = useState(null);
useEffect(() => {
if (localStorage.getItem('accessToken')) {
http
.get('/user/auth')
.then((res) => {
setUser(res.data.user);
// Set the selectedImage to the current profile picture when the component mounts
})
.catch((error) => {
console.error(error);
// Handle the error
});
}
}, []);
const profilePicture = user?.image;
const formik = useFormik({
initialValues: {
name: user ? user.name : '',
email: user ? user.email : '',
phone: user ? user.phone : '',
address: user ? user.address : '',
profilePicture: ' ',
},
enableReinitialize: true,
validationSchema: yup.object().shape({
name: yup
.string()
.trim()
.min(3, 'Name must be at least 3 characters')
.max(100, 'Name must be at most 100 characters')
.required('Name is required'),
email: yup.string().trim().email('Invalid email').required('Email is required'),
phone: yup.string().trim().max(20, 'Phone must be at most 20 characters'),
address: yup.string().trim().max(100, 'Address must be at most 100 characters').nullable(),
profilePicture: yup.mixed().nullable(),
}),
onSubmit: (data) => {
data.name = data.name.trim();
data.email = data.email.trim();
if (data.phone) {
data.phone = data.phone.trim();
}
if (data.address) {
data.address = data.address.trim();
}
const formData = new FormData();
formData.append('name', data.name);
formData.append('email', data.email);
formData.append('phone', data.phone);
formData.append('address', data.address);
formData.append('profilePicture', data.profilePicture || '');
http
.put(`/user/profile/${user.id}`, formData)
.then((res) => {
console.log(res.data);
toast.success('Profile updated successfully!');
})
.catch((error) => {
console.error(error);
toast.error('Error updating profile. Please try again.');
});
},
});
return (
<Box sx={{ marginTop: '10px' }}>
<Grid container spacing={2}>
<Grid item xs={12} md={4}>
<Box
sx={{
border: '1px solid black',
p: 2,
marginTop: '10px',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
}}
>
{user && (
<>
<img
src={profilePicture}
alt="Profile"
style={{ width: '200px', height: '200px', borderRadius: '50%' }}
/>
<Typography variant="h6" sx={{ mt: 2 }}>
{user.name}
</Typography>
</>
)}
</Box>
<List component="nav" sx={{ border: '1px solid gray', marginTop: '10px' }} disablePadding>
<Divider />
<ListItem divider>
<ListItemIcon>
<PermIdentityIcon />
</ListItemIcon>
<ListItemText primary="Account Details" />
</ListItem>
<ListItem divider>
<ListItemIcon>
<PermIdentityIcon />
</ListItemIcon>
<ListItemText primary="Change Password" />
</ListItem>
<ListItem divider>
<ListItemIcon>
<PermIdentityIcon />
</ListItemIcon>
<ListItemText primary="Credit Card Detail" />
</ListItem>
</List>
</Grid>
<Grid item xs={12} md={8}>
<Box sx={{ border: '1px solid black', p: 2, borderRadius: 1 }}>
<Typography variant="h5" sx={{ mb: 2 }}>
Customer Profile
</Typography>
<Box component="form" onSubmit={formik.handleSubmit}>
<Grid container spacing={2} alignItems="center">
<Grid item xs={12} md={6}>
<TextField
fullWidth
margin="normal"
autoComplete="off"
label="Name"
name="name"
value={formik.values.name}
onChange={formik.handleChange}
error={formik.touched.name && Boolean(formik.errors.name)}
helperText={formik.touched.name && formik.errors.name}
/>
<TextField
fullWidth
margin="normal"
autoComplete="off"
label="Email"
name="email"
value={formik.values.email}
onChange={formik.handleChange}
error={formik.touched.email && Boolean(formik.errors.email)}
helperText={formik.touched.email && formik.errors.email}
/>
<TextField
fullWidth
margin="normal"
autoComplete="off"
label="Phone"
name="phone"
value={formik.values.phone}
onChange={formik.handleChange}
error={formik.touched.phone && Boolean(formik.errors.phone)}
helperText={formik.touched.phone && formik.errors.phone}
/>
<TextField
fullWidth
margin="normal"
autoComplete="off"
label="Address"
name="address"
value={formik.values.address}
onChange={formik.handleChange}
error={formik.touched.address && Boolean(formik.errors.address)}
helperText={formik.touched.address && formik.errors.address}
/>
</Grid>
<Grid item xs={12} md={6} style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
{selectedImage ? (
// If an image is selected, show the uploaded profile picture
<img
src={URL.createObjectURL(selectedImage)}
alt="Uploaded Profile"
style={{ width: '100px', height: '100px', borderRadius: '50%' }}
/>
) : (
// If no image is selected, show the current profile picture or a default picture
<img
src={profilePicture || "default-profile-picture.jpg"}
alt="Profile"
style={{ width: '100px', height: '100px', borderRadius: '50%' }}
/>
)}
{/* Profile picture input to update the picture */}
<input
type="file"
name="profilePicture"
accept="image/*"
onChange={(event) => {
formik.setFieldValue('profilePicture', event.currentTarget.files[0]);
setSelectedImage(event.currentTarget.files[0]);
}}
style={{ display: 'none' }}
id="profilePictureInput"
/>
<label htmlFor="profilePictureInput">
<Button component="span">Choose Image</Button>
</label>
{formik.touched.profilePicture && formik.errors.profilePicture && (
<Typography color="error">{formik.errors.profilePicture}</Typography>
)}
</Grid>
</Grid>
<Button variant="contained" type="submit">
UPDATE
</Button>
</Box>
</Box>
</Grid>
</Grid>
</Box>
);
}
Profiles.propTypes = {
// Add any prop types if needed
};
export default Profiles;
字符串
我收到这两个错误,但我不明白为什么我会得到这个错误突然我想它更新这个配置文件prefutly
1条答案
按热度按时间eqzww0vc1#
验证错误,指示在提交表单时未提供姓名和电子邮件字段。可能存在与useEffect钩子相关的计时问题,该钩子获取用户数据。Formik表单初始化可能在用户数据可用之前发生,导致表单字段为空并导致验证错误。在你的例子中,当用户数据被提取时,似乎没有发生formik重新初始化。您可以采取不同的方法来确保重新初始化。
我建议你调查一下,找到适合你情况的最佳方法。有一个单独的useEffect来触发formik的重新初始化,从技术上讲也是可行的。就像这样
字符串