微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

res.data

如何解决res.data

我正在制作前端组件,它将上传用户的封面照片和头像照片这两个不同的图像。我使用 node.js 作为我的后端与 express.js。如果用户上传封面照片,后端将发送 res.send(如果图像是 coverPhoto 或 avatarPhoto,它会保护图像路径)。但是我在用户上传图像后如何上传它们时遇到问题。我习惯于不同的 useState userInfo.coverPhoto 和 userInfo.avatarPhoto。问题是在用户单击coverPhoto 然后单击avatarPhoto 后,coverPhoto 的图像src 将损坏图像。但刷新后图像就会出现。

userProfile.js
    import React,{ useState,useEffect } from 'react';
import { usedispatch,useSelector } from 'react-redux';
import axios from 'axios';
import PersonIcon from '@material-ui/icons/Person';
import {
  Container,Grid,Typography,TextField,Button,Modal,Backdrop,} from '@material-ui/core';
import Card from '@material-ui/core/Card';
import CardContent from '@material-ui/core/CardContent';
import CardMedia from '@material-ui/core/CardMedia';
import ImageIcon from '@material-ui/icons/Image';
import AccountCircleIcon from '@material-ui/icons/AccountCircle';
import { useForm } from 'react-hook-form';
import FormContainer from '../components/FormContainer';
import useStyles from '../styles/style';
import {
  getDetailsUser,updateDetailsUser,} from '../redux/actions/userActions';

const ProfilePage = ({ history }) => {
  const userDetails = useSelector((state) => state.userDetails);
  const { user } = userDetails;

  const userLogin = useSelector((state) => state.userLogin);
  const { userData } = userLogin;

  const userUpdateDetails = useSelector((state) => state.userUpdateDetails);
  const { userUpdate } = userUpdateDetails;

  const [userInfo,setUserInfo] = useState({
    id: user._id,username: '',email: '',fullname: '',coverPhoto: '',avatarPhoto: '',about: '',mainAddress: '',country: '',city: '',zipcode: '',});
  const [coverPreview,setCoverPreview] = useState('');
  const [avatarPreview,setAvatarPreview] = useState('');
  const [open,setopen] = useState(false);
  const dispatch = usedispatch();
  const classes = useStyles();

  useEffect(() => {
    if (!userData) {
      history.push('/user/login');
    } else {
      if (!user || !user.username || userUpdate) {
        dispatch(getDetailsUser('profile'));
        // if (!userInfo.coverPhoto) {
        //   document.getElementById(
        //     'coverPhoto-file-button'
        //   ).nextElementSibling.style.opacity = '0';
        // }
      } else {
        setUserInfo(user);
      }
    }
  },[userData,user,userUpdate,history]);

  const handleClose = () => {
    setopen(false);
  };

  const handleChange = (level) => (e) => {
    e.preventDefault();
    if (!level) {
      setUserInfo({
        ...userInfo,[e.target.name]: e.target.value,});
    } else {
      setUserInfo({
        ...userInfo,[level]: {
          ...userInfo[level],},});
    }
  };

  const uploadCoverPhotoHandler = async (e) => {
    const imgFile = e.target.files[0];
    const imgFieldName = e.target.name;

    if (imgFile.type !== 'image/jpeg' && imgFile.type !== 'image/png') {
      console.log('wrong format');
    }

    let formData = new FormData();
    formData.append(imgFieldName,imgFile);

    try {
      await axios({
        method: 'POST',url: 'http://localhost:5000/user/profile',data: formData,headers: {
          'content-type': 'multipart/form-data',}).then((res) => {
        if (imgFieldName === 'coverPhoto') {
          setUserInfo({ coverPhoto: res.data });
        } else {
          setUserInfo({ avatarPhoto: res.data });
        }
      });
    } catch (error) {
      console.log(error.response);
    }
  };

  const onSubmit = async (e) => {
    dispatch(updateDetailsUser(userInfo));
    setopen(true);
  };

  const { register,handleSubmit,errors,getValues } = useForm({
    mode: 'onSubmit',reValidateMode: 'onBlur',});

  return (
    <FormContainer>
      <Container component="div" className={classes.profileContainer}>
        <Modal
          className={classes.modal}
          open={open}
          closeAfterTransition
          BackdropComponent={Backdrop}
          BackdropProps={{
            root: classes.modalRoot,timeout: 500,}}
        >
          <div className={classes.modalContainer}>
            <Typography
              component="h1"
              variant="h5"
              className={classes.promptTitle}
            >
              Account has been updated!
            </Typography>
            <Button
              type="submit"
              variant="contained"
              className={classes.button}
              onClick={handleClose}
              style={{ width: '60%',marginBottom: '2.5rem' }}
            >
              Close
            </Button>
          </div>
        </Modal>
        <Grid item xs={12}>
          <Card className={classes.userProfileCard}>
            <CardContent>
              <form novalidate onSubmit={handleSubmit(onSubmit)}>
                <Typography
                  component="h1"
                  variant="h4"
                  className={classes.titleProfile}
                >
                  <PersonIcon
                    style={{
                      position: 'relative',top: '5px',marginRight: '0.2em',}}
                  />
                  Edit Profile
                </Typography>
                <Grid container spacing={2}>
                  <Grid item xs={6}>
                    <TextField
                      variant="outlined"
                      id="username"
                      name="username"
                      type="text"
                      label="Username"
                      value={userInfo && userInfo.username}
                      onChange={handleChange()}
                      fullWidth
                      InputLabelProps={{
                        classes: {
                          root: classes.label,focused: classes.focused,shrink: true,}}
                      InputProps={{
                        className: classes.textfield,classes: {
                          root: classes.cssOutlinedInput,focused: classes.cssFocused,notchedOutline: classes.notchedOutline,}}
                      inputRef={register({
                        required: 'You must provide an username.',minLength: {
                          value: 4,message:
                            'Your username must be greater than 4 characters',pattern: {
                          value: /^[A-Za-z0-9_]+$/i,message:
                            'Username may only have letters,number and underscores.',})}
                    />
                    {errors.username && (
                      <span className={classes.error}>
                        {errors.username.message}
                      </span>
                    )}
                  </Grid>
                  <Grid item xs={6}>
                    <TextField
                      variant="outlined"
                      id="email"
                      name="email"
                      type="email"
                      label="Email"
                      value={userInfo && userInfo.email}
                      onChange={handleChange()}
                      fullWidth
                      InputLabelProps={{
                        classes: {
                          root: classes.label,}}
                      inputRef={register({
                        required: 'You must provide a email.',pattern: {
                          value: /^[^@ ]+@[^@ ]+\.[^@ .]{2,}$/,message: 'You must provide a valid email address!',})}
                    />
                    {errors.email && (
                      <span className={classes.error}>
                        {errors.email.message}
                      </span>
                    )}
                  </Grid>
                  <Grid item xs={12}>
                    <TextField
                      variant="outlined"
                      id="fullname"
                      name="fullname"
                      type="text"
                      label="Fullname"
                      value={userInfo && userInfo.fullname}
                      onChange={handleChange()}
                      fullWidth
                      InputLabelProps={{
                        classes: {
                          root: classes.label,}}
                      inputRef={register({
                        required: 'You must provide a fullname.',minLength: {
                          value: 6,message:
                            'Your password must be greater than 6 characters',pattern: {
                          value: /^[A-Za-z ]+$/i,message: 'Alphabetical characters only',})}
                    />
                    {errors.fullname && (
                      <span className={classes.error}>
                        {errors.fullname.message}
                      </span>
                    )}
                  </Grid>
                  <Grid item xs={12}>
                    <TextField
                      variant="outlined"
                      id="mainAddress"
                      name="mainAddress"
                      type="text"
                      label="Address"
                      value={userInfo.address && userInfo.address.mainAddress}
                      onChange={handleChange('address')}
                      fullWidth
                      InputLabelProps={{
                        classes: {
                          root: classes.label,}}
                    />
                  </Grid>
                  <Grid item xs={2}>
                    <TextField
                      variant="outlined"
                      id="city"
                      name="city"
                      type="text"
                      label="City"
                      value={userInfo.address && userInfo.address.city}
                      onChange={handleChange('address')}
                      fullWidth
                      InputLabelProps={{
                        classes: {
                          root: classes.label,}}
                    />
                  </Grid>
                  <Grid item xs={2}>
                    <TextField
                      variant="outlined"
                      id="country"
                      name="country"
                      type="text"
                      label="Country"
                      value={userInfo.address && userInfo.address.country}
                      onChange={handleChange('address')}
                      fullWidth
                      InputLabelProps={{
                        classes: {
                          root: classes.label,}}
                    />
                  </Grid>
                  <Grid item xs={2}>
                    <TextField
                      variant="outlined"
                      id="zipcode"
                      name="zipcode"
                      type="text"
                      label="Zipcode"
                      value={userInfo.address && userInfo.address.zipcode}
                      onChange={handleChange('address')}
                      fullWidth
                      InputLabelProps={{
                        shrink: true,classes: {
                          root: classes.label,}}
                      inputRef={register({
                        pattern: {
                          value: /^[0-9]+([0-9]+)?$/,message: 'Numbers only',})}
                    />
                    {errors.zipcode && (
                      <span className={classes.error}>
                        {errors.zipcode.message}
                      </span>
                    )}
                  </Grid>
                  <Grid item xs={12}>
                    <Grid item xs={12}>
                      <TextField
                        variant="outlined"
                        id="aboutme"
                        name="about"
                        type="text"
                        label="About me"
                        value={userInfo && userInfo.about}
                        onChange={handleChange()}
                        fullWidth
                        multiline
                        rows={2}
                        InputLabelProps={{
                          classes: {
                            root: classes.label,}}
                        InputProps={{
                          className: classes.textfield,classes: {
                            root: classes.cssOutlinedInput,}}
                      />
                    </Grid>
                  </Grid>
                  <Grid item xs={2}>
                    <Button
                      type="submit"
                      fullWidth
                      variant="contained"
                      className={classes.button}
                    >
                      Update
                    </Button>
                  </Grid>
                </Grid>
              </form>
            </CardContent>
          </Card>
        </Grid>
        <Grid item xs={12}>
          <Card className={classes.userCard}>
            <form id="userPhoto">
              <CardContent className={classes.coverPhotoContainer}>
                <CardMedia
                  component="img"
                  src={userInfo && userInfo.coverPhoto}
                  height="180rem"
                  onload="this.style.display=''"
                />
                <input
                  accept="image/*"
                  id="coverPhoto-file-button"
                  type="file"
                  name="coverPhoto"
                  style={{ display: 'none' }}
                  onChange={uploadCoverPhotoHandler}
                />
                <label htmlFor="coverPhoto-file-button">
                  <ImageIcon />
                  Add Cover Photo
                </label>
              </CardContent>
              <CardContent className={classes.imgProfileContainer}>
                <CardMedia
                  component="img"
                  src={userInfo && userInfo.avatarPhoto}
                  height="180rem"
                  onload="this.style.display=''"
                />
                <input
                  accept="image/*"
                  id="imgProfile-file-button"
                  type="file"
                  name="avatarPhoto"
                  style={{ display: 'none' }}
                  onChange={uploadCoverPhotoHandler}
                />
                <label htmlFor="imgProfile-file-button">
                  <AccountCircleIcon />
                </label>
              </CardContent>
            </form>
            <CardContent>
              <Typography
                className={classes.titleProfileUsername}
                variant="h6"
                component="h1"
              >
                {userInfo && userInfo.username}
              </Typography>
              <Typography
                className={classes.profileAbout}
                variant="body2"
                component="p"
              ></Typography>
            </CardContent>
          </Card>
        </Grid>
      </Container>
    </FormContainer>
  );
};

export default ProfilePage;

错误 这将在上传头像照片后发生,封面照片中的图像将消失,但在我刷新页面后,它将再次出现。

enter image description here

解决方法

useState 在类组件中的作用与 this.setState 不同。

在写入 setUserInfo({ coverPhoto: res.data }) 时,您从 userInfo 中删除所有其他字段。

你需要写:

setUserInfo(prevState => ({ ...prevState,coverPhoto: res.data }))

}).then((res) => {
        if (imgFieldName === 'coverPhoto') {
         setUserInfo(prevState => ({ ...prevState,coverPhoto: res.data }));
        } else {
          setUserInfo(prevState => ({ ...prevState,avatarPhoto: res.data }));
        }
      });

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。