首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在等待XMLHttpRequest从API中获取时,如何放置加载图标?

在等待XMLHttpRequest从API中获取时,如何放置加载图标?
EN

Stack Overflow用户
提问于 2022-07-29 16:05:59
回答 1查看 199关注 0票数 1

我目前正在处理注册页面,每当用户添加配置文件图片时,通常需要一段时间才能显示照片(1-3秒),而在加载时,我想要放置一个加载图标,以向用户表示他们的图像需要一些时间上传(调用Cloudinary获取图像url)。我试着执行了,但没有结果。

下面是我的代码:

代码语言:javascript
复制
import { useDispatch, useSelector } from "react-redux";

import { VectorIllustration } from "./VectorIllustration";
import { Avatar, Text, Loading } from '@nextui-org/react'
import { Button, IconButton, InputAdornment, TextField } from "@mui/material";
import '../../style-sheets/CreateYourProfile.css'
import { createUsers } from "../../reducers/usersReducer";
import AddAPhotoIcon from '@mui/icons-material/AddAPhoto';
import AvatarPicture from '../../images/AvatarPicture.png'
import DescriptionIcon from '@mui/icons-material/Description';
import Select from 'react-select';
import makeAnimated from 'react-select/animated';
import userInformation from "../../services/userInformation";
import { useState } from "react";

const CreateYourProfile = () => {
  const [loading, setLoading] = useState(false);
  const state = useSelector(state => state)
  const dispatch = useDispatch()
  const animatedComponents = makeAnimated();
  console.log(state)

  const handleImageSubmit = async (e) => {
    const formData = new FormData()
    formData.append('file', e.target.files[0]);
    formData.append('upload_preset', process.env.REACT_APP_CLOUDINARY_PRESET)
    formData.append('api_key', process.env.REACT_APP_CLOUDINARY_APIKEY)
    const xhr = new XMLHttpRequest()
    xhr.open('POST', process.env.REACT_APP_CLOUDINARY_URL, false)
    xhr.send(formData);
    const imageResponse = await JSON.parse(xhr.responseText)
    setLoading(true)
    dispatch(createUsers(imageResponse.secure_url, 'profileImageURL'))
  }

  const handlePostUserToServer = async () => {
    const response = await userInformation.newUser(state.users)
    console.log(response)
  }

  const listOfAddictions = [{value: 'Alcohol', label: 'Alcohol'}, {value: 'Lust (Porn, sex, etc.)', label: 'Lust (Porn, sex, etc.)'}, {value:'Gambling', label: 'Gambling'}, {value: 'Food', label: 'Food'}, {value: 'Drugs', label: 'Drugs'}, {value: 'Nicotine', label: 'Nicotine'}, {value: 'Work', label: 'Work'}, {value: 'Pills', label: 'Pills'},
{value: 'Cocaine', label: 'Cocaine'}, {value: 'Crystal Meth', label: 'Crystal Meth'}, {value: 'Emotions', label: 'Emotions'}, {value: 'Marijuana', label: 'Marijuana'}, {value: 'Narcotics', label: 'Narcotics'}]

  const listOfGroups = [{value: 'Alcoholics Anonymous', label: 'Alcoholics Anonymous'}, {value: 'Cocaine Anonymous', label: 'Cocaine Anonymous'}, {value: 'Crystal Meth Anonymous', label: 'Crystal Meth Anonymous'}, {value: 'Emotions Anonymous', label: 'Emotions Anonymous' },{value: 'Eating Disorder Anonymous', label: 'Eating Disorder Anonymous'}, {value: 'Food Addicts in Recovery Anonymous', label: 'Food Addicts in Recovery Anonymous'},
 {value: 'Food Addicts Anonymous', label: 'Food Addicts Anonymous'}, {value: 'Gamblers Anonymous', label: 'Gamblers Anonymous'}, {value: 'Heroin Anonymous', label: 'Heroin Anonymous'}, {value: 'Love Addicts Anonymous', label: 'Love Addicts Anonymous'}, {value: 'Marijuana Anonymous', label: 'Marijuana Anonymous'}, {value: 'Narcotics Anonymous', label: 'Narcotics Anonymous'}, {value: 'Neurotics Anonymous', label: 'Neurotics Anonymous'}, {value: 'Nicotine Anonymous', label: 'Nicotine Anonymous'},
 {value: 'Overeaters Anonymous', label: 'Overeaters Anonymous'}, {value: 'Pills Anonymous', label: 'Pills Anonymous'}, {value: 'Racists Anonymous', label: 'Racists Anonymous'}, {value: 'Sexaholics Anonymous', label: 'Sexaholics Anonymous'}, {value: 'Sex Addicts Anonymous', label: 'Sex Addicts Anonymous'}, {value: 'Sexual Compulsives Anonymous', label: 'Sexual Compulsives Anonymous'}, {value: 'Sex and Love Addicts Anonymous', label: 'Sex and Love Addicts Anonymous'}, {value: 'Sexual Recovery Anonymous', label: 'Sexual Recovery Anonymous'},
 {value: 'Workaholics Anonymous', label: 'Workaholics Anonymous'}, {value: 'Racists Anonymous', label: 'Racists Anonymous'}]

  return (
    <div className="create-profile-page-container">
      <VectorIllustration />
      <div className="create-profile-form-container">   
          <input
            accept="image/*"
            id="contained-button-file"
            type="file"
            hidden
            aria-disabled={true}
            onChange={handleImageSubmit}
          />
        <label htmlFor="contained-button-file">
          <IconButton style={{left: '40%', top: '10%'}} component='span'>
            {state.users.profileImageURL ? <Avatar src={state.users.profileImageURL} text={state.users.name} style={{width: '132px', height: '132px'}}/> : loading ? <Loading style={{width: '132px', height: '132px'}}/> : <Avatar src={AvatarPicture} text={state.users.name} style={{width: '132px', height: '132px'}}/>}
          </IconButton>
          <Button component='span' startIcon={<AddAPhotoIcon />} size='medium' style={{position: 'absolute', left: '35%', top: '25%'}}>Upload Profile Picture</Button>
        </label>
        <TextField multiline rows={5} label='Briefly Describe Yourself' style={{position: 'absolute', top: '35%', left: '32%', width: '300px', backgroundColor: 'white'}} inputProps={{
          maxLength: 250
        }} InputProps={{
          endAdornment: (
            <InputAdornment>
              <DescriptionIcon color="primary"/>
            </InputAdornment>
          )
        }}  onChange={(e) => {
          dispatch(createUsers(e.target.value, 'biography'))
        }}/>
        <Text style={{position: 'absolute', top: '54.5%', left: '31%', fontFamily: 'cursive'}} b size={24}>What do you struggle with?</Text>
        <Select
          closeMenuOnScroll={false}
          components={animatedComponents}
          defaultValue=''
          isMulti
          options={listOfAddictions}
          closeMenuOnSelect={false}
          className='addiction-selector'
          onChange={(e) => {
            dispatch(createUsers(e.map(addiction => addiction?.value), 'addictions'))}}
        />
        <Text style={{position: 'absolute', top: '67%', left: '24%', fontFamily: 'cursive'}} b size={24}>Do you belong to any of these groups?</Text>
        <Select
          closeMenuOnScroll={false}
          components={animatedComponents}
          defaultValue=''
          isMulti
          options={listOfGroups}
          closeMenuOnSelect={false}
          className='group-selector'
          onChange={(e) => dispatch(createUsers(e.map(group => group?.value), 'groups'))}
        />
        <Button className="submit-button" sx={{ position: 'absolute', color: 'white', top: '90%' }} type='submit' onClick={handlePostUserToServer}>Submit</Button>
        </div>
    </div>
  )
}

export default CreateYourProfile;

我正在使用NextUI的加载组件作为图标..。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-29 17:13:28

所以首先关闭,当提交是点击你已经设置加载为真,这是很好的。之后,您需要显示that组件,方法是只显示that状态是否为true,因此在{that& }完成后,将其设置为false。

代码语言:javascript
复制
<div className="create-profile-page-container">
      <VectorIllustration />
      {Loading && <YourNextUILoadingSpinner/> }
      <div className="create-profile-form-container">   
          <input
            accept="image/*"
            id="contained-button-file"
            type="file"
            hidden
            aria-disabled={true}
            onChange={handleImageSubmit}
          />
        <label htmlFor="contained-button-file">
          <IconButton style={{left: '40%', top: '10%'}} component='span'>
            {state.users.profileImageURL ? <Avatar src={state.users.profileImageURL} text={state.users.name} style={{width: '132px', height: '132px'}}/> : loading ? <Loading style={{width: '132px', height: '132px'}}/> : <Avatar src={AvatarPicture} text={state.users.name} style={{width: '132px', height: '132px'}}/>}
          </IconButton>
          <Button component='span' startIcon={<AddAPhotoIcon />} size='medium' style={{position: 'absolute', left: '35%', top: '25%'}}>Upload Profile Picture</Button>
        </label>
        <TextField multiline rows={5} label='Briefly Describe Yourself' style={{position: 'absolute', top: '35%', left: '32%', width: '300px', backgroundColor: 'white'}} inputProps={{
          maxLength: 250
        }} InputProps={{
          endAdornment: (
            <InputAdornment>
              <DescriptionIcon color="primary"/>
            </InputAdornment>
          )
        }}  onChange={(e) => {
          dispatch(createUsers(e.target.value, 'biography'))
        }}/>
        <Text style={{position: 'absolute', top: '54.5%', left: '31%', fontFamily: 'cursive'}} b size={24}>What do you struggle with?</Text>
        <Select
          closeMenuOnScroll={false}
          components={animatedComponents}
          defaultValue=''
          isMulti
          options={listOfAddictions}
          closeMenuOnSelect={false}
          className='addiction-selector'
          onChange={(e) => {
            dispatch(createUsers(e.map(addiction => addiction?.value), 'addictions'))}}
        />
        <Text style={{position: 'absolute', top: '67%', left: '24%', fontFamily: 'cursive'}} b size={24}>Do you belong to any of these groups?</Text>
        <Select
          closeMenuOnScroll={false}
          components={animatedComponents}
          defaultValue=''
          isMulti
          options={listOfGroups}
          closeMenuOnSelect={false}
          className='group-selector'
          onChange={(e) => dispatch(createUsers(e.map(group => group?.value), 'groups'))}
        />
        <Button className="submit-button" sx={{ position: 'absolute', color: 'white', top: '90%' }} type='submit' onClick={handlePostUserToServer}>Submit</Button>
        </div>
    </div>

另一种方法是使用设置超时3秒,而不是设置为false。

代码语言:javascript
复制
setTimeout(() => {
  setLoading(false)
  console.log("Delayed for 3 second.");
}, "3000")

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73168108

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档